| Current File : /home/mmdealscpanel/yummmdeals.com/ruby32.tar |
include/rb_mjit_min_header-3.2.8.h 0000644 00000002517 15040330601 0012604 0 ustar 00 /*
* Kluge to support multilib installation of both 32- and 64-bit RPMS:
* we need to arrange that header files that appear in both RPMs are
* identical. Hence, this file is architecture-independent and calls
* in an arch-dependent file that will appear in just one RPM.
*
* To avoid breaking arches not explicitly supported by Red Hat, we
* use this indirection file *only* on known multilib arches.
*
* We pay attention to include _only_ the original multilib-unclean
* header file. Including any other system-header file could cause
* unpredictable include-ordering issues (rhbz#1412274, comment #16).
*
* Note: this may well fail if user tries to use gcc's -I- option.
* But that option is deprecated anyway.
*/
#if defined(__x86_64__)
#include "rb_mjit_min_header-3.2.8-x86_64.h"
#elif defined(__i386__)
#include "rb_mjit_min_header-3.2.8-i386.h"
#elif defined(__ppc64__) || defined(__powerpc64__)
#include "rb_mjit_min_header-3.2.8-ppc64.h"
#elif defined(__ppc__) || defined(__powerpc__)
#include "rb_mjit_min_header-3.2.8-ppc.h"
#elif defined(__s390x__)
#include "rb_mjit_min_header-3.2.8-s390x.h"
#elif defined(__s390__)
#include "rb_mjit_min_header-3.2.8-s390.h"
#elif defined(__sparc__) && defined(__arch64__)
#include "rb_mjit_min_header-3.2.8-sparc64.h"
#elif defined(__sparc__)
#include "rb_mjit_min_header-3.2.8-sparc.h"
#endif
include/ruby.h 0000644 00000002543 15040330601 0007315 0 ustar 00 #ifndef RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_H 1
/**
* @author $Author$
* @date Sun 10 12:06:15 Jun JST 2007
* @copyright 2007-2008 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#define HAVE_RUBY_ATOMIC_H 1
#define HAVE_RUBY_DEBUG_H 1
#define HAVE_RUBY_DEFINES_H 1
#define HAVE_RUBY_ENCODING_H 1
#define HAVE_RUBY_FIBER_SCHEDULER_H 1
#define HAVE_RUBY_INTERN_H 1
#define HAVE_RUBY_IO_H 1
#define HAVE_RUBY_MEMORY_VIEW_H 1
#define HAVE_RUBY_MISSING_H 1
#define HAVE_RUBY_ONIGMO_H 1
#define HAVE_RUBY_ONIGURUMA_H 1
#define HAVE_RUBY_RACTOR_H 1
#define HAVE_RUBY_RANDOM_H 1
#define HAVE_RUBY_RE_H 1
#define HAVE_RUBY_REGEX_H 1
#define HAVE_RUBY_RUBY_H 1
#define HAVE_RUBY_ST_H 1
#define HAVE_RUBY_THREAD_H 1
#define HAVE_RUBY_THREAD_NATIVE_H 1
#define HAVE_RUBY_UTIL_H 1
#define HAVE_RUBY_VERSION_H 1
#define HAVE_RUBY_VM_H 1
#ifdef _WIN32
#define HAVE_RUBY_WIN32_H 1
#endif
#include "ruby/ruby.h"
#endif /* RUBY_H */
include/rb_mjit_min_header-3.2.8-x86_64.h 0000644 00004522000 15040330601 0013536 0 ustar 00 #ifdef __GNUC__
# pragma GCC system_header
#endif
#define ALWAYS_INLINE(x) __attribute__ ((__always_inline__)) x
typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;
typedef long unsigned int size_t;
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
typedef __int8_t __int_least8_t;
typedef __uint8_t __uint_least8_t;
typedef __int16_t __int_least16_t;
typedef __uint16_t __uint_least16_t;
typedef __int32_t __int_least32_t;
typedef __uint32_t __uint_least32_t;
typedef __int64_t __int_least64_t;
typedef __uint64_t __uint_least64_t;
typedef long int __quad_t;
typedef unsigned long int __u_quad_t;
typedef long int __intmax_t;
typedef unsigned long int __uintmax_t;
typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
typedef unsigned long int __nlink_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef int __pid_t;
typedef struct { int __val[2]; } __fsid_t;
typedef long int __clock_t;
typedef unsigned long int __rlim_t;
typedef unsigned long int __rlim64_t;
typedef unsigned int __id_t;
typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;
typedef int __daddr_t;
typedef int __key_t;
typedef int __clockid_t;
typedef void * __timer_t;
typedef long int __blksize_t;
typedef long int __blkcnt_t;
typedef long int __blkcnt64_t;
typedef unsigned long int __fsblkcnt_t;
typedef unsigned long int __fsblkcnt64_t;
typedef unsigned long int __fsfilcnt_t;
typedef unsigned long int __fsfilcnt64_t;
typedef long int __fsword_t;
typedef long int __ssize_t;
typedef long int __syscall_slong_t;
typedef unsigned long int __syscall_ulong_t;
typedef __off64_t __loff_t;
typedef char *__caddr_t;
typedef long int __intptr_t;
typedef unsigned int __socklen_t;
typedef int __sig_atomic_t;
typedef struct
{
int __count;
union
{
unsigned int __wch;
char __wchb[4];
} __value;
} __mbstate_t;
typedef struct _G_fpos_t
{
__off_t __pos;
__mbstate_t __state;
} __fpos_t;
typedef struct _G_fpos64_t
{
__off64_t __pos;
__mbstate_t __state;
} __fpos64_t;
struct _IO_FILE;
typedef struct _IO_FILE __FILE;
struct _IO_FILE;
typedef struct _IO_FILE FILE;
struct _IO_FILE;
struct _IO_marker;
struct _IO_codecvt;
struct _IO_wide_data;
typedef void _IO_lock_t;
struct _IO_FILE
{
int _flags;
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
char *_IO_write_base;
char *_IO_write_ptr;
char *_IO_write_end;
char *_IO_buf_base;
char *_IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
__off64_t _offset;
struct _IO_codecvt *_codecvt;
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
size_t __pad5;
int _mode;
char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
};
typedef __ssize_t cookie_read_function_t (void *__cookie, char *__buf,
size_t __nbytes);
typedef __ssize_t cookie_write_function_t (void *__cookie, const char *__buf,
size_t __nbytes);
typedef int cookie_seek_function_t (void *__cookie, __off64_t *__pos, int __w);
typedef int cookie_close_function_t (void *__cookie);
typedef struct _IO_cookie_io_functions_t
{
cookie_read_function_t *read;
cookie_write_function_t *write;
cookie_seek_function_t *seek;
cookie_close_function_t *close;
} cookie_io_functions_t;
typedef __off_t off_t;
typedef __off64_t off64_t;
typedef __ssize_t ssize_t;
typedef __fpos_t fpos_t;
typedef __fpos64_t fpos64_t;
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));
extern int renameat (int __oldfd, const char *__old, int __newfd,
const char *__new) __attribute__ ((__nothrow__ , __leaf__));
extern int renameat2 (int __oldfd, const char *__old, int __newfd,
const char *__new, unsigned int __flags) __attribute__ ((__nothrow__ , __leaf__));
extern FILE *tmpfile (void) __attribute__ ((__warn_unused_result__));
extern FILE *tmpfile64 (void) __attribute__ ((__warn_unused_result__));
extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *tempnam (const char *__dir, const char *__pfx)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__));
extern int fclose (FILE *__stream);
extern int fflush (FILE *__stream);
extern int fflush_unlocked (FILE *__stream);
extern int fcloseall (void);
extern FILE *fopen (const char *__restrict __filename,
const char *__restrict __modes) __attribute__ ((__warn_unused_result__));
extern FILE *freopen (const char *__restrict __filename,
const char *__restrict __modes,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern FILE *fopen64 (const char *__restrict __filename,
const char *__restrict __modes) __attribute__ ((__warn_unused_result__));
extern FILE *freopen64 (const char *__restrict __filename,
const char *__restrict __modes,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern FILE *fopencookie (void *__restrict __magic_cookie,
const char *__restrict __modes,
cookie_io_functions_t __io_funcs) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
size_t __size) __attribute__ ((__nothrow__ , __leaf__));
extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int fprintf (FILE *__restrict __stream,
const char *__restrict __format, ...);
extern int printf (const char *__restrict __format, ...);
extern int sprintf (char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__));
extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg);
extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);
extern int vsprintf (char *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg) __attribute__ ((__nothrow__));
extern int snprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));
extern int vsnprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
extern int vasprintf (char **__restrict __ptr, const char *__restrict __f,
__gnuc_va_list __arg)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 0))) __attribute__ ((__warn_unused_result__));
extern int __asprintf (char **__restrict __ptr,
const char *__restrict __fmt, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) __attribute__ ((__warn_unused_result__));
extern int asprintf (char **__restrict __ptr,
const char *__restrict __fmt, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) __attribute__ ((__warn_unused_result__));
extern int vdprintf (int __fd, const char *__restrict __fmt,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__printf__, 2, 0)));
extern int dprintf (int __fd, const char *__restrict __fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
extern int fscanf (FILE *__restrict __stream,
const char *__restrict __format, ...) __attribute__ ((__warn_unused_result__));
extern int scanf (const char *__restrict __format, ...) __attribute__ ((__warn_unused_result__));
extern int sscanf (const char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__warn_unused_result__));
extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 1, 0))) __attribute__ ((__warn_unused_result__));
extern int vsscanf (const char *__restrict __s,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));
extern int fgetc (FILE *__stream);
extern int getc (FILE *__stream);
extern int getchar (void);
extern int getc_unlocked (FILE *__stream);
extern int getchar_unlocked (void);
extern int fgetc_unlocked (FILE *__stream);
extern int fputc (int __c, FILE *__stream);
extern int putc (int __c, FILE *__stream);
extern int putchar (int __c);
extern int fputc_unlocked (int __c, FILE *__stream);
extern int putc_unlocked (int __c, FILE *__stream);
extern int putchar_unlocked (int __c);
extern int getw (FILE *__stream);
extern int putw (int __w, FILE *__stream);
extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
__attribute__ ((__warn_unused_result__));
extern char *fgets_unlocked (char *__restrict __s, int __n,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern __ssize_t __getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern __ssize_t getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern __ssize_t getline (char **__restrict __lineptr,
size_t *__restrict __n,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern int fputs (const char *__restrict __s, FILE *__restrict __stream);
extern int puts (const char *__s);
extern int ungetc (int __c, FILE *__stream);
extern size_t fread (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern size_t fwrite (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s);
extern int fputs_unlocked (const char *__restrict __s,
FILE *__restrict __stream);
extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream);
extern int fseek (FILE *__stream, long int __off, int __whence);
extern long int ftell (FILE *__stream) __attribute__ ((__warn_unused_result__));
extern void rewind (FILE *__stream);
extern int fseeko (FILE *__stream, __off_t __off, int __whence);
extern __off_t ftello (FILE *__stream) __attribute__ ((__warn_unused_result__));
extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);
extern int fsetpos (FILE *__stream, const fpos_t *__pos);
extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence);
extern __off64_t ftello64 (FILE *__stream) __attribute__ ((__warn_unused_result__));
extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos);
extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos);
extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void perror (const char *__s);
extern int sys_nerr;
extern const char *const sys_errlist[];
extern int _sys_nerr;
extern const char *const _sys_errlist[];
extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern FILE *popen (const char *__command, const char *__modes) __attribute__ ((__warn_unused_result__));
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
extern char *cuserid (char *__s);
struct obstack;
extern int obstack_printf (struct obstack *__restrict __obstack,
const char *__restrict __format, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3)));
extern int obstack_vprintf (struct obstack *__restrict __obstack,
const char *__restrict __format,
__gnuc_va_list __args)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 0)));
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
extern __inline __attribute__ ((__gnu_inline__)) int
getchar (void)
{
return getc (stdin);
}
extern __inline __attribute__ ((__gnu_inline__)) int
fgetc_unlocked (FILE *__fp)
{
return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++);
}
extern __inline __attribute__ ((__gnu_inline__)) int
getc_unlocked (FILE *__fp)
{
return (__builtin_expect (((__fp)->_IO_read_ptr >= (__fp)->_IO_read_end), 0) ? __uflow (__fp) : *(unsigned char *) (__fp)->_IO_read_ptr++);
}
extern __inline __attribute__ ((__gnu_inline__)) int
getchar_unlocked (void)
{
return (__builtin_expect (((stdin)->_IO_read_ptr >= (stdin)->_IO_read_end), 0) ? __uflow (stdin) : *(unsigned char *) (stdin)->_IO_read_ptr++);
}
extern __inline __attribute__ ((__gnu_inline__)) int
putchar (int __c)
{
return putc (__c, stdout);
}
extern __inline __attribute__ ((__gnu_inline__)) int
fputc_unlocked (int __c, FILE *__stream)
{
return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c)));
}
extern __inline __attribute__ ((__gnu_inline__)) int
putc_unlocked (int __c, FILE *__stream)
{
return (__builtin_expect (((__stream)->_IO_write_ptr >= (__stream)->_IO_write_end), 0) ? __overflow (__stream, (unsigned char) (__c)) : (unsigned char) (*(__stream)->_IO_write_ptr++ = (__c)));
}
extern __inline __attribute__ ((__gnu_inline__)) int
putchar_unlocked (int __c)
{
return (__builtin_expect (((stdout)->_IO_write_ptr >= (stdout)->_IO_write_end), 0) ? __overflow (stdout, (unsigned char) (__c)) : (unsigned char) (*(stdout)->_IO_write_ptr++ = (__c)));
}
extern __inline __attribute__ ((__gnu_inline__)) __ssize_t
getline (char **__lineptr, size_t *__n, FILE *__stream)
{
return __getdelim (__lineptr, __n, '\n', __stream);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) feof_unlocked (FILE *__stream)
{
return (((__stream)->_flags & 0x0010) != 0);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) ferror_unlocked (FILE *__stream)
{
return (((__stream)->_flags & 0x0020) != 0);
}
extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
const char *__restrict __format,
__gnuc_va_list __ap) __attribute__ ((__nothrow__ , __leaf__));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) sprintf (char *__restrict __s, const char *__restrict __fmt, ...)
{
return __builtin___sprintf_chk (__s, 2 - 1,
__builtin_object_size (__s, 2 > 1), __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) vsprintf (char *__restrict __s, const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __builtin___vsprintf_chk (__s, 2 - 1,
__builtin_object_size (__s, 2 > 1), __fmt, __ap);
}
extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
size_t __slen, const char *__restrict __format,
...) __attribute__ ((__nothrow__ , __leaf__));
extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
size_t __slen, const char *__restrict __format,
__gnuc_va_list __ap) __attribute__ ((__nothrow__ , __leaf__));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) snprintf (char *__restrict __s, size_t __n, const char *__restrict __fmt, ...)
{
return __builtin___snprintf_chk (__s, __n, 2 - 1,
__builtin_object_size (__s, 2 > 1), __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) vsnprintf (char *__restrict __s, size_t __n, const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __builtin___vsnprintf_chk (__s, __n, 2 - 1,
__builtin_object_size (__s, 2 > 1), __fmt, __ap);
}
extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
const char *__restrict __format, ...);
extern int __printf_chk (int __flag, const char *__restrict __format, ...);
extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
const char *__restrict __format, __gnuc_va_list __ap);
extern int __vprintf_chk (int __flag, const char *__restrict __format,
__gnuc_va_list __ap);
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)
{
return __fprintf_chk (__stream, 2 - 1, __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
printf (const char *__restrict __fmt, ...)
{
return __printf_chk (2 - 1, __fmt, __builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
vprintf (const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __vfprintf_chk (stdout, 2 - 1, __fmt, __ap);
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
vfprintf (FILE *__restrict __stream,
const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __vfprintf_chk (__stream, 2 - 1, __fmt, __ap);
}
extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt,
...) __attribute__ ((__format__ (__printf__, 3, 4)));
extern int __vdprintf_chk (int __fd, int __flag,
const char *__restrict __fmt, __gnuc_va_list __arg)
__attribute__ ((__format__ (__printf__, 3, 0)));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
dprintf (int __fd, const char *__restrict __fmt, ...)
{
return __dprintf_chk (__fd, 2 - 1, __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __vdprintf_chk (__fd, 2 - 1, __fmt, __ap);
}
extern int __asprintf_chk (char **__restrict __ptr, int __flag,
const char *__restrict __fmt, ...)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__printf__, 3, 4))) __attribute__ ((__warn_unused_result__));
extern int __vasprintf_chk (char **__restrict __ptr, int __flag,
const char *__restrict __fmt, __gnuc_va_list __arg)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__printf__, 3, 0))) __attribute__ ((__warn_unused_result__));
extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
int __flag, const char *__restrict __format,
...)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__printf__, 3, 4)));
extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack,
int __flag,
const char *__restrict __format,
__gnuc_va_list __args)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__printf__, 3, 0)));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...)
{
return __asprintf_chk (__ptr, 2 - 1, __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) __asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...)
{
return __asprintf_chk (__ptr, 2 - 1, __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) obstack_printf (struct obstack *__restrict __obstack, const char *__restrict __fmt, ...)
{
return __obstack_printf_chk (__obstack, 2 - 1, __fmt,
__builtin_va_arg_pack ());
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) vasprintf (char **__restrict __ptr, const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __vasprintf_chk (__ptr, 2 - 1, __fmt, __ap);
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) obstack_vprintf (struct obstack *__restrict __obstack, const char *__restrict __fmt, __gnuc_va_list __ap)
{
return __obstack_vprintf_chk (__obstack, 2 - 1, __fmt,
__ap);
}
extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern char *__fgets_alias (char *__restrict __s, int __n, FILE *__restrict __stream) __asm__ ("" "fgets") __attribute__ ((__warn_unused_result__));
extern char *__fgets_chk_warn (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) __asm__ ("" "__fgets_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fgets called with bigger size than length " "of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char *
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
{
size_t sz = __builtin_object_size (__s, 2 > 1);
if (((__builtin_constant_p (sz) && (sz) == (long unsigned int) -1) || (((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= ((sz)) / ((sizeof (char))))) && (((long unsigned int) (__n)) <= ((sz)) / ((sizeof (char)))))))
return __fgets_alias (__s, __n, __stream);
if ((((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= (sz) / (sizeof (char)))) && !(((long unsigned int) (__n)) <= (sz) / (sizeof (char)))))
return __fgets_chk_warn (__s, sz, __n, __stream);
return __fgets_chk (__s, sz, __n, __stream);
}
extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen,
size_t __size, size_t __n,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern size_t __fread_alias (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "fread") __attribute__ ((__warn_unused_result__));
extern size_t __fread_chk_warn (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fread called with bigger size * nmemb than length " "of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) size_t
fread (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
size_t sz = __builtin_object_size (__ptr, 0);
if (((__builtin_constant_p (sz) && (sz) == (long unsigned int) -1) || (((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= ((sz)) / ((__size)))) && (((long unsigned int) (__n)) <= ((sz)) / ((__size))))))
return __fread_alias (__ptr, __size, __n, __stream);
if ((((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= (sz) / (__size))) && !(((long unsigned int) (__n)) <= (sz) / (__size))))
return __fread_chk_warn (__ptr, sz, __size, __n, __stream);
return __fread_chk (__ptr, sz, __size, __n, __stream);
}
extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
int __n, FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern char *__fgets_unlocked_alias (char *__restrict __s, int __n, FILE *__restrict __stream) __asm__ ("" "fgets_unlocked") __attribute__ ((__warn_unused_result__));
extern char *__fgets_unlocked_chk_warn (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) __asm__ ("" "__fgets_unlocked_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fgets_unlocked called with bigger size than length " "of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char *
fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
{
size_t sz = __builtin_object_size (__s, 2 > 1);
if (((__builtin_constant_p (sz) && (sz) == (long unsigned int) -1) || (((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= ((sz)) / ((sizeof (char))))) && (((long unsigned int) (__n)) <= ((sz)) / ((sizeof (char)))))))
return __fgets_unlocked_alias (__s, __n, __stream);
if ((((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= (sz) / (sizeof (char)))) && !(((long unsigned int) (__n)) <= (sz) / (sizeof (char)))))
return __fgets_unlocked_chk_warn (__s, sz, __n, __stream);
return __fgets_unlocked_chk (__s, sz, __n, __stream);
}
extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen,
size_t __size, size_t __n,
FILE *__restrict __stream) __attribute__ ((__warn_unused_result__));
extern size_t __fread_unlocked_alias (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "fread_unlocked") __attribute__ ((__warn_unused_result__));
extern size_t __fread_unlocked_chk_warn (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_unlocked_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fread_unlocked called with bigger size * nmemb than " "length of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) size_t
fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
size_t sz = __builtin_object_size (__ptr, 0);
if (((__builtin_constant_p (sz) && (sz) == (long unsigned int) -1) || (((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= ((sz)) / ((__size)))) && (((long unsigned int) (__n)) <= ((sz)) / ((__size))))))
{
if (__builtin_constant_p (__size)
&& __builtin_constant_p (__n)
&& (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2))
&& __size * __n <= 8)
{
size_t __cnt = __size * __n;
char *__cptr = (char *) __ptr;
if (__cnt == 0)
return 0;
for (; __cnt > 0; --__cnt)
{
int __c = getc_unlocked (__stream);
if (__c == (-1))
break;
*__cptr++ = __c;
}
return (__cptr - (char *) __ptr) / __size;
}
return __fread_unlocked_alias (__ptr, __size, __n, __stream);
}
if ((((__typeof (__n)) 0 < (__typeof (__n)) -1 || (__builtin_constant_p (__n) && (__n) > 0)) && __builtin_constant_p ((((long unsigned int) (__n)) <= (sz) / (__size))) && !(((long unsigned int) (__n)) <= (sz) / (__size))))
return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream);
return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream);
}
typedef __u_char u_char;
typedef __u_short u_short;
typedef __u_int u_int;
typedef __u_long u_long;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;
typedef __fsid_t fsid_t;
typedef __loff_t loff_t;
typedef __ino_t ino_t;
typedef __ino64_t ino64_t;
typedef __dev_t dev_t;
typedef __gid_t gid_t;
typedef __mode_t mode_t;
typedef __nlink_t nlink_t;
typedef __uid_t uid_t;
typedef __pid_t pid_t;
typedef __id_t id_t;
typedef __daddr_t daddr_t;
typedef __caddr_t caddr_t;
typedef __key_t key_t;
typedef __clock_t clock_t;
typedef __clockid_t clockid_t;
typedef __time_t time_t;
typedef __timer_t timer_t;
typedef __useconds_t useconds_t;
typedef __suseconds_t suseconds_t;
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
typedef __int8_t int8_t;
typedef __int16_t int16_t;
typedef __int32_t int32_t;
typedef __int64_t int64_t;
typedef __uint8_t u_int8_t;
typedef __uint16_t u_int16_t;
typedef __uint32_t u_int32_t;
typedef __uint64_t u_int64_t;
typedef int register_t __attribute__ ((__mode__ (__word__)));
static __inline __uint16_t
__bswap_16 (__uint16_t __bsx)
{
return __builtin_bswap16 (__bsx);
}
static __inline __uint32_t
__bswap_32 (__uint32_t __bsx)
{
return __builtin_bswap32 (__bsx);
}
__extension__ static __inline __uint64_t
__bswap_64 (__uint64_t __bsx)
{
return __builtin_bswap64 (__bsx);
}
static __inline __uint16_t
__uint16_identity (__uint16_t __x)
{
return __x;
}
static __inline __uint32_t
__uint32_identity (__uint32_t __x)
{
return __x;
}
static __inline __uint64_t
__uint64_identity (__uint64_t __x)
{
return __x;
}
typedef struct
{
unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))];
} __sigset_t;
typedef __sigset_t sigset_t;
struct timeval
{
__time_t tv_sec;
__suseconds_t tv_usec;
};
struct timespec
{
__time_t tv_sec;
__syscall_slong_t tv_nsec;
};
typedef long int __fd_mask;
typedef struct
{
__fd_mask fds_bits[1024 / (8 * (int) sizeof (__fd_mask))];
} fd_set;
typedef __fd_mask fd_mask;
extern int select (int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
struct timeval *__restrict __timeout);
extern int pselect (int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
const struct timespec *__restrict __timeout,
const __sigset_t *__restrict __sigmask);
extern long int __fdelt_chk (long int __d);
extern long int __fdelt_warn (long int __d)
__attribute__((__warning__ ("bit outside of fd_set selected")));
typedef __blksize_t blksize_t;
typedef __blkcnt_t blkcnt_t;
typedef __fsblkcnt_t fsblkcnt_t;
typedef __fsfilcnt_t fsfilcnt_t;
typedef __blkcnt64_t blkcnt64_t;
typedef __fsblkcnt64_t fsblkcnt64_t;
typedef __fsfilcnt64_t fsfilcnt64_t;
struct __pthread_rwlock_arch_t
{
unsigned int __readers;
unsigned int __writers;
unsigned int __wrphase_futex;
unsigned int __writers_futex;
unsigned int __pad3;
unsigned int __pad4;
int __cur_writer;
int __shared;
signed char __rwelision;
unsigned char __pad1[7];
unsigned long int __pad2;
unsigned int __flags;
};
typedef struct __pthread_internal_list
{
struct __pthread_internal_list *__prev;
struct __pthread_internal_list *__next;
} __pthread_list_t;
struct __pthread_mutex_s
{
int __lock ;
unsigned int __count;
int __owner;
unsigned int __nusers;
int __kind;
short __spins; short __elision;
__pthread_list_t __list;
};
struct __pthread_cond_s
{
__extension__ union
{
__extension__ unsigned long long int __wseq;
struct
{
unsigned int __low;
unsigned int __high;
} __wseq32;
};
__extension__ union
{
__extension__ unsigned long long int __g1_start;
struct
{
unsigned int __low;
unsigned int __high;
} __g1_start32;
};
unsigned int __glibc_unused___g_refs[2] ;
unsigned int __g_size[2];
unsigned int __g1_orig_size;
unsigned int __wrefs;
unsigned int __g_signals[2];
};
typedef unsigned long int pthread_t;
typedef union
{
char __size[4];
int __align;
} pthread_mutexattr_t;
typedef union
{
char __size[4];
int __align;
} pthread_condattr_t;
typedef unsigned int pthread_key_t;
typedef int pthread_once_t;
union pthread_attr_t
{
char __size[56];
long int __align;
};
typedef union pthread_attr_t pthread_attr_t;
typedef union
{
struct __pthread_mutex_s __data;
char __size[40];
long int __align;
} pthread_mutex_t;
typedef union
{
struct __pthread_cond_s __data;
char __size[48];
__extension__ long long int __align;
} pthread_cond_t;
typedef union
{
struct __pthread_rwlock_arch_t __data;
char __size[56];
long int __align;
} pthread_rwlock_t;
typedef union
{
char __size[8];
long int __align;
} pthread_rwlockattr_t;
typedef volatile int pthread_spinlock_t;
typedef union
{
char __size[32];
long int __align;
} pthread_barrier_t;
typedef union
{
char __size[4];
int __align;
} pthread_barrierattr_t;
struct stat
{
__dev_t st_dev;
__ino_t st_ino;
__nlink_t st_nlink;
__mode_t st_mode;
__uid_t st_uid;
__gid_t st_gid;
int __pad0;
__dev_t st_rdev;
__off_t st_size;
__blksize_t st_blksize;
__blkcnt_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
__syscall_slong_t __glibc_reserved[3];
};
struct stat64
{
__dev_t st_dev;
__ino64_t st_ino;
__nlink_t st_nlink;
__mode_t st_mode;
__uid_t st_uid;
__gid_t st_gid;
int __pad0;
__dev_t st_rdev;
__off_t st_size;
__blksize_t st_blksize;
__blkcnt64_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
__syscall_slong_t __glibc_reserved[3];
};
extern int stat (const char *__restrict __file,
struct stat *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int fstat (int __fd, struct stat *__buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int stat64 (const char *__restrict __file,
struct stat64 *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int fstat64 (int __fd, struct stat64 *__buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int fstatat (int __fd, const char *__restrict __file,
struct stat *__restrict __buf, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int fstatat64 (int __fd, const char *__restrict __file,
struct stat64 *__restrict __buf, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int lstat (const char *__restrict __file,
struct stat *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int lstat64 (const char *__restrict __file,
struct stat64 *__restrict __buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int chmod (const char *__file, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int lchmod (const char *__file, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int fchmod (int __fd, __mode_t __mode) __attribute__ ((__nothrow__ , __leaf__));
extern int fchmodat (int __fd, const char *__file, __mode_t __mode,
int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__));
extern __mode_t umask (__mode_t __mask) __attribute__ ((__nothrow__ , __leaf__));
extern __mode_t getumask (void) __attribute__ ((__nothrow__ , __leaf__));
extern int mkdir (const char *__path, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int mkdirat (int __fd, const char *__path, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int mknodat (int __fd, const char *__path, __mode_t __mode,
__dev_t __dev) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int mkfifo (const char *__path, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int mkfifoat (int __fd, const char *__path, __mode_t __mode)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int utimensat (int __fd, const char *__path,
const struct timespec __times[2],
int __flags)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int futimens (int __fd, const struct timespec __times[2]) __attribute__ ((__nothrow__ , __leaf__));
extern int __fxstat (int __ver, int __fildes, struct stat *__stat_buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int __xstat (int __ver, const char *__filename,
struct stat *__stat_buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int __lxstat (int __ver, const char *__filename,
struct stat *__stat_buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int __fxstatat (int __ver, int __fildes, const char *__filename,
struct stat *__stat_buf, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4)));
extern int __fxstat64 (int __ver, int __fildes, struct stat64 *__stat_buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int __xstat64 (int __ver, const char *__filename,
struct stat64 *__stat_buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int __lxstat64 (int __ver, const char *__filename,
struct stat64 *__stat_buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int __fxstatat64 (int __ver, int __fildes, const char *__filename,
struct stat64 *__stat_buf, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4)));
extern int __xmknod (int __ver, const char *__path, __mode_t __mode,
__dev_t *__dev) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 4)));
extern int __xmknodat (int __ver, int __fd, const char *__path,
__mode_t __mode, __dev_t *__dev)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 5)));
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
typedef struct {
unsigned long fds_bits[1024 / (8 * sizeof(long))];
} __kernel_fd_set;
typedef void (*__kernel_sighandler_t)(int);
typedef int __kernel_key_t;
typedef int __kernel_mqd_t;
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
typedef unsigned long __kernel_old_dev_t;
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
typedef __kernel_ulong_t __kernel_ino_t;
typedef unsigned int __kernel_mode_t;
typedef int __kernel_pid_t;
typedef int __kernel_ipc_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
typedef __kernel_long_t __kernel_suseconds_t;
typedef int __kernel_daddr_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
typedef __kernel_ulong_t __kernel_size_t;
typedef __kernel_long_t __kernel_ssize_t;
typedef __kernel_long_t __kernel_ptrdiff_t;
typedef struct {
int val[2];
} __kernel_fsid_t;
typedef __kernel_long_t __kernel_off_t;
typedef long long __kernel_loff_t;
typedef __kernel_long_t __kernel_old_time_t;
typedef __kernel_long_t __kernel_time_t;
typedef long long __kernel_time64_t;
typedef __kernel_long_t __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;
typedef __u64 __le64;
typedef __u64 __be64;
typedef __u16 __sum16;
typedef __u32 __wsum;
typedef unsigned __poll_t;
struct statx_timestamp {
__s64 tv_sec;
__u32 tv_nsec;
__s32 __reserved;
};
struct statx {
__u32 stx_mask;
__u32 stx_blksize;
__u64 stx_attributes;
__u32 stx_nlink;
__u32 stx_uid;
__u32 stx_gid;
__u16 stx_mode;
__u16 __spare0[1];
__u64 stx_ino;
__u64 stx_size;
__u64 stx_blocks;
__u64 stx_attributes_mask;
struct statx_timestamp stx_atime;
struct statx_timestamp stx_btime;
struct statx_timestamp stx_ctime;
struct statx_timestamp stx_mtime;
__u32 stx_rdev_major;
__u32 stx_rdev_minor;
__u32 stx_dev_major;
__u32 stx_dev_minor;
__u64 __spare2[14];
};
int statx (int __dirfd, const char *__restrict __path, int __flags,
unsigned int __mask, struct statx *__restrict __buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 5)));
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) stat (const char *__path, struct stat *__statbuf)
{
return __xstat (1, __path, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) lstat (const char *__path, struct stat *__statbuf)
{
return __lxstat (1, __path, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) fstat (int __fd, struct stat *__statbuf)
{
return __fxstat (1, __fd, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) fstatat (int __fd, const char *__filename, struct stat *__statbuf, int __flag)
{
return __fxstatat (1, __fd, __filename, __statbuf, __flag);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) mknod (const char *__path, __mode_t __mode, __dev_t __dev)
{
return __xmknod (0, __path, __mode, &__dev);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) mknodat (int __fd, const char *__path, __mode_t __mode, __dev_t __dev)
{
return __xmknodat (0, __fd, __path, __mode, &__dev);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) stat64 (const char *__path, struct stat64 *__statbuf)
{
return __xstat64 (1, __path, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) lstat64 (const char *__path, struct stat64 *__statbuf)
{
return __lxstat64 (1, __path, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) fstat64 (int __fd, struct stat64 *__statbuf)
{
return __fxstat64 (1, __fd, __statbuf);
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) fstatat64 (int __fd, const char *__filename, struct stat64 *__statbuf, int __flag)
{
return __fxstatat64 (1, __fd, __filename, __statbuf, __flag);
}
typedef int wchar_t;
typedef struct
{
int quot;
int rem;
} div_t;
typedef struct
{
long int quot;
long int rem;
} ldiv_t;
__extension__ typedef struct
{
long long int quot;
long long int rem;
} lldiv_t;
extern size_t __ctype_get_mb_cur_max (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern double atof (const char *__nptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int atoi (const char *__nptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern long int atol (const char *__nptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
__extension__ extern long long int atoll (const char *__nptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern double strtod (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern float strtof (const char *__restrict __nptr,
char **__restrict __endptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern long double strtold (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern _Float32 strtof32 (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern _Float64 strtof64 (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern _Float128 strtof128 (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern _Float32x strtof32x (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern _Float64x strtof64x (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern long int strtol (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern unsigned long int strtoul (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
__extension__
extern long long int strtoq (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
__extension__
extern unsigned long long int strtouq (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
__extension__
extern long long int strtoll (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
__extension__
extern unsigned long long int strtoull (const char *__restrict __nptr,
char **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int strfromd (char *__dest, size_t __size, const char *__format,
double __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf (char *__dest, size_t __size, const char *__format,
float __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfroml (char *__dest, size_t __size, const char *__format,
long double __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf32 (char *__dest, size_t __size, const char * __format,
_Float32 __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf64 (char *__dest, size_t __size, const char * __format,
_Float64 __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf128 (char *__dest, size_t __size, const char * __format,
_Float128 __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf32x (char *__dest, size_t __size, const char * __format,
_Float32x __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int strfromf64x (char *__dest, size_t __size, const char * __format,
_Float64x __f)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
struct __locale_struct
{
struct __locale_data *__locales[13];
const unsigned short int *__ctype_b;
const int *__ctype_tolower;
const int *__ctype_toupper;
const char *__names[13];
};
typedef struct __locale_struct *__locale_t;
typedef __locale_t locale_t;
extern long int strtol_l (const char *__restrict __nptr,
char **__restrict __endptr, int __base,
locale_t __loc) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 4)));
extern unsigned long int strtoul_l (const char *__restrict __nptr,
char **__restrict __endptr,
int __base, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 4)));
__extension__
extern long long int strtoll_l (const char *__restrict __nptr,
char **__restrict __endptr, int __base,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 4)));
__extension__
extern unsigned long long int strtoull_l (const char *__restrict __nptr,
char **__restrict __endptr,
int __base, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 4)));
extern double strtod_l (const char *__restrict __nptr,
char **__restrict __endptr, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern float strtof_l (const char *__restrict __nptr,
char **__restrict __endptr, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern long double strtold_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern _Float32 strtof32_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern _Float64 strtof64_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern _Float128 strtof128_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern _Float32x strtof32x_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern _Float64x strtof64x_l (const char *__restrict __nptr,
char **__restrict __endptr,
locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) atoi (const char *__nptr)
{
return (int) strtol (__nptr, (char **) ((void *)0), 10);
}
extern __inline __attribute__ ((__gnu_inline__)) long int
__attribute__ ((__nothrow__ , __leaf__)) atol (const char *__nptr)
{
return strtol (__nptr, (char **) ((void *)0), 10);
}
__extension__ extern __inline __attribute__ ((__gnu_inline__)) long long int
__attribute__ ((__nothrow__ , __leaf__)) atoll (const char *__nptr)
{
return strtoll (__nptr, (char **) ((void *)0), 10);
}
extern char *l64a (long int __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern long int a64l (const char *__s)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern long int random (void) __attribute__ ((__nothrow__ , __leaf__));
extern void srandom (unsigned int __seed) __attribute__ ((__nothrow__ , __leaf__));
extern char *initstate (unsigned int __seed, char *__statebuf,
size_t __statelen) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern char *setstate (char *__statebuf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
struct random_data
{
int32_t *fptr;
int32_t *rptr;
int32_t *state;
int rand_type;
int rand_deg;
int rand_sep;
int32_t *end_ptr;
};
extern int random_r (struct random_data *__restrict __buf,
int32_t *__restrict __result) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int srandom_r (unsigned int __seed, struct random_data *__buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int initstate_r (unsigned int __seed, char *__restrict __statebuf,
size_t __statelen,
struct random_data *__restrict __buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 4)));
extern int setstate_r (char *__restrict __statebuf,
struct random_data *__restrict __buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int rand (void) __attribute__ ((__nothrow__ , __leaf__));
extern void srand (unsigned int __seed) __attribute__ ((__nothrow__ , __leaf__));
extern int rand_r (unsigned int *__seed) __attribute__ ((__nothrow__ , __leaf__));
extern double drand48 (void) __attribute__ ((__nothrow__ , __leaf__));
extern double erand48 (unsigned short int __xsubi[3]) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern long int lrand48 (void) __attribute__ ((__nothrow__ , __leaf__));
extern long int nrand48 (unsigned short int __xsubi[3])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern long int mrand48 (void) __attribute__ ((__nothrow__ , __leaf__));
extern long int jrand48 (unsigned short int __xsubi[3])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void srand48 (long int __seedval) __attribute__ ((__nothrow__ , __leaf__));
extern unsigned short int *seed48 (unsigned short int __seed16v[3])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void lcong48 (unsigned short int __param[7]) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
struct drand48_data
{
unsigned short int __x[3];
unsigned short int __old_x[3];
unsigned short int __c;
unsigned short int __init;
__extension__ unsigned long long int __a;
};
extern int drand48_r (struct drand48_data *__restrict __buffer,
double *__restrict __result) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int erand48_r (unsigned short int __xsubi[3],
struct drand48_data *__restrict __buffer,
double *__restrict __result) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int lrand48_r (struct drand48_data *__restrict __buffer,
long int *__restrict __result)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int nrand48_r (unsigned short int __xsubi[3],
struct drand48_data *__restrict __buffer,
long int *__restrict __result)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int mrand48_r (struct drand48_data *__restrict __buffer,
long int *__restrict __result)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int jrand48_r (unsigned short int __xsubi[3],
struct drand48_data *__restrict __buffer,
long int *__restrict __result)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int srand48_r (long int __seedval, struct drand48_data *__buffer)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int seed48_r (unsigned short int __seed16v[3],
struct drand48_data *__buffer) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int lcong48_r (unsigned short int __param[7],
struct drand48_data *__buffer)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *malloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__));
extern void *calloc (size_t __nmemb, size_t __size)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__));
extern void *realloc (void *__ptr, size_t __size)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void *reallocarray (void *__ptr, size_t __nmemb, size_t __size)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));
extern void *alloca (size_t __size) __attribute__ ((__nothrow__ , __leaf__));
extern void *valloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__warn_unused_result__));
extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern void *aligned_alloc (size_t __alignment, size_t __size)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__alloc_size__ (2))) __attribute__ ((__warn_unused_result__));
extern void abort (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
extern int atexit (void (*__func) (void)) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int at_quick_exit (void (*__func) (void)) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void exit (int __status) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
extern void quick_exit (int __status) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
extern void _Exit (int __status) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
extern char *getenv (const char *__name) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern char *secure_getenv (const char *__name)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int putenv (char *__string) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int setenv (const char *__name, const char *__value, int __replace)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int unsetenv (const char *__name) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int clearenv (void) __attribute__ ((__nothrow__ , __leaf__));
extern char *mktemp (char *__template) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int mkstemp (char *__template) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkstemp64 (char *__template) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkstemps (char *__template, int __suffixlen) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkstemps64 (char *__template, int __suffixlen)
__attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern char *mkdtemp (char *__template) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkostemp (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkostemp64 (char *__template, int __flags) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkostemps (char *__template, int __suffixlen, int __flags)
__attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int mkostemps64 (char *__template, int __suffixlen, int __flags)
__attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int system (const char *__command) __attribute__ ((__warn_unused_result__));
extern char *canonicalize_file_name (const char *__name)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern char *realpath (const char *__restrict __name,
char *__restrict __resolved) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
typedef int (*__compar_fn_t) (const void *, const void *);
typedef __compar_fn_t comparison_fn_t;
typedef int (*__compar_d_fn_t) (const void *, const void *, void *);
extern void *bsearch (const void *__key, const void *__base,
size_t __nmemb, size_t __size, __compar_fn_t __compar)
__attribute__ ((__nonnull__ (1, 2, 5))) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__gnu_inline__)) void *
bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
__compar_fn_t __compar)
{
size_t __l, __u, __idx;
const void *__p;
int __comparison;
__l = 0;
__u = __nmemb;
while (__l < __u)
{
__idx = (__l + __u) / 2;
__p = (void *) (((const char *) __base) + (__idx * __size));
__comparison = (*__compar) (__key, __p);
if (__comparison < 0)
__u = __idx;
else if (__comparison > 0)
__l = __idx + 1;
else
return (void *) __p;
}
return ((void *)0);
}
extern void qsort (void *__base, size_t __nmemb, size_t __size,
__compar_fn_t __compar) __attribute__ ((__nonnull__ (1, 4)));
extern void qsort_r (void *__base, size_t __nmemb, size_t __size,
__compar_d_fn_t __compar, void *__arg)
__attribute__ ((__nonnull__ (1, 4)));
extern int abs (int __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
extern long int labs (long int __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
__extension__ extern long long int llabs (long long int __x)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
extern div_t div (int __numer, int __denom)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
extern ldiv_t ldiv (long int __numer, long int __denom)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
__extension__ extern lldiv_t lldiv (long long int __numer,
long long int __denom)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)) __attribute__ ((__warn_unused_result__));
extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt,
int *__restrict __sign) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__));
extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt,
int *__restrict __sign) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__));
extern char *gcvt (double __value, int __ndigit, char *__buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3))) __attribute__ ((__warn_unused_result__));
extern char *qecvt (long double __value, int __ndigit,
int *__restrict __decpt, int *__restrict __sign)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__));
extern char *qfcvt (long double __value, int __ndigit,
int *__restrict __decpt, int *__restrict __sign)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4))) __attribute__ ((__warn_unused_result__));
extern char *qgcvt (long double __value, int __ndigit, char *__buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3))) __attribute__ ((__warn_unused_result__));
extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt,
int *__restrict __sign, char *__restrict __buf,
size_t __len) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4, 5)));
extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt,
int *__restrict __sign, char *__restrict __buf,
size_t __len) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4, 5)));
extern int qecvt_r (long double __value, int __ndigit,
int *__restrict __decpt, int *__restrict __sign,
char *__restrict __buf, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4, 5)));
extern int qfcvt_r (long double __value, int __ndigit,
int *__restrict __decpt, int *__restrict __sign,
char *__restrict __buf, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3, 4, 5)));
extern int mblen (const char *__s, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
extern int mbtowc (wchar_t *__restrict __pwc,
const char *__restrict __s, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
extern int wctomb (char *__s, wchar_t __wchar) __attribute__ ((__nothrow__ , __leaf__));
extern size_t mbstowcs (wchar_t *__restrict __pwcs,
const char *__restrict __s, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
extern size_t wcstombs (char *__restrict __s,
const wchar_t *__restrict __pwcs, size_t __n)
__attribute__ ((__nothrow__ , __leaf__));
extern int rpmatch (const char *__response) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int getsubopt (char **__restrict __optionp,
char *const *__restrict __tokens,
char **__restrict __valuep)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2, 3))) __attribute__ ((__warn_unused_result__));
extern int posix_openpt (int __oflag) __attribute__ ((__warn_unused_result__));
extern int grantpt (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern int unlockpt (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern char *ptsname (int __fd) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int ptsname_r (int __fd, char *__buf, size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int getpt (void);
extern int getloadavg (double __loadavg[], int __nelem)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern __inline __attribute__ ((__gnu_inline__)) double
__attribute__ ((__nothrow__ , __leaf__)) atof (const char *__nptr)
{
return strtod (__nptr, (char **) ((void *)0));
}
extern char *__realpath_chk (const char *__restrict __name,
char *__restrict __resolved,
size_t __resolvedlen) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *__realpath_alias (const char *__restrict __name, char *__restrict __resolved) __asm__ ("" "realpath") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *__realpath_chk_warn (const char *__restrict __name, char *__restrict __resolved, size_t __resolvedlen) __asm__ ("" "__realpath_chk") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__))
__attribute__((__warning__ ("second argument of realpath must be either NULL or at " "least PATH_MAX bytes long buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char *
__attribute__ ((__nothrow__ , __leaf__)) realpath (const char *__restrict __name, char *__restrict __resolved)
{
size_t sz = __builtin_object_size (__resolved, 2 > 1);
if (sz == (size_t) -1)
return __realpath_alias (__name, __resolved);
return __realpath_chk (__name, __resolved, sz);
}
extern int __ptsname_r_chk (int __fd, char *__buf, size_t __buflen,
size_t __nreal) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int __ptsname_r_alias (int __fd, char *__buf, size_t __buflen) __asm__ ("" "ptsname_r") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2)));
extern int __ptsname_r_chk_warn (int __fd, char *__buf, size_t __buflen, size_t __nreal) __asm__ ("" "__ptsname_r_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2))) __attribute__((__warning__ ("ptsname_r called with buflen bigger than " "size of buf")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) ptsname_r (int __fd, char *__buf, size_t __buflen)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __ptsname_r_alias (__fd, __buf, __buflen) : ((((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __ptsname_r_chk_warn (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1)) : __ptsname_r_chk (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1))));
}
extern int __wctomb_chk (char *__s, wchar_t __wchar, size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int __wctomb_alias (char *__s, wchar_t __wchar) __asm__ ("" "wctomb") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) int
__attribute__ ((__nothrow__ , __leaf__)) wctomb (char *__s, wchar_t __wchar)
{
if (__builtin_object_size (__s, 2 > 1) != (size_t) -1
&& 16 > __builtin_object_size (__s, 2 > 1))
return __wctomb_chk (__s, __wchar, __builtin_object_size (__s, 2 > 1));
return __wctomb_alias (__s, __wchar);
}
extern size_t __mbstowcs_chk (wchar_t *__restrict __dst,
const char *__restrict __src,
size_t __len, size_t __dstlen) __attribute__ ((__nothrow__ , __leaf__));
extern size_t __mbstowcs_alias (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len) __asm__ ("" "mbstowcs") __attribute__ ((__nothrow__ , __leaf__));
extern size_t __mbstowcs_chk_warn (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len, size_t __dstlen) __asm__ ("" "__mbstowcs_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__((__warning__ ("mbstowcs called with dst buffer smaller than len " "* sizeof (wchar_t)")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) size_t
__attribute__ ((__nothrow__ , __leaf__)) mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, size_t __len)
{
return (((__builtin_constant_p (__builtin_object_size (__dst, 2 > 1)) && (__builtin_object_size (__dst, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= ((__builtin_object_size (__dst, 2 > 1))) / ((sizeof (wchar_t))))) && (((long unsigned int) (__len)) <= ((__builtin_object_size (__dst, 2 > 1))) / ((sizeof (wchar_t)))))) ? __mbstowcs_alias (__dst, __src, __len) : ((((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= (__builtin_object_size (__dst, 2 > 1)) / (sizeof (wchar_t)))) && !(((long unsigned int) (__len)) <= (__builtin_object_size (__dst, 2 > 1)) / (sizeof (wchar_t)))) ? __mbstowcs_chk_warn (__dst, __src, __len, (__builtin_object_size (__dst, 2 > 1)) / (sizeof (wchar_t))) : __mbstowcs_chk (__dst, __src, __len, (__builtin_object_size (__dst, 2 > 1)) / (sizeof (wchar_t)))));
}
extern size_t __wcstombs_chk (char *__restrict __dst,
const wchar_t *__restrict __src,
size_t __len, size_t __dstlen) __attribute__ ((__nothrow__ , __leaf__));
extern size_t __wcstombs_alias (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len) __asm__ ("" "wcstombs") __attribute__ ((__nothrow__ , __leaf__));
extern size_t __wcstombs_chk_warn (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len, size_t __dstlen) __asm__ ("" "__wcstombs_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__((__warning__ ("wcstombs called with dst buffer smaller than len")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) size_t
__attribute__ ((__nothrow__ , __leaf__)) wcstombs (char *__restrict __dst, const wchar_t *__restrict __src, size_t __len)
{
return (((__builtin_constant_p (__builtin_object_size (__dst, 2 > 1)) && (__builtin_object_size (__dst, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= ((__builtin_object_size (__dst, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__len)) <= ((__builtin_object_size (__dst, 2 > 1))) / ((sizeof (char)))))) ? __wcstombs_alias (__dst, __src, __len) : ((((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= (__builtin_object_size (__dst, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__len)) <= (__builtin_object_size (__dst, 2 > 1)) / (sizeof (char)))) ? __wcstombs_chk_warn (__dst, __src, __len, __builtin_object_size (__dst, 2 > 1)) : __wcstombs_chk (__dst, __src, __len, __builtin_object_size (__dst, 2 > 1))));
}
typedef long int ptrdiff_t;
typedef struct {
long long __max_align_ll __attribute__((__aligned__(__alignof__(long long))));
long double __max_align_ld __attribute__((__aligned__(__alignof__(long double))));
} max_align_t;
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *memmove (void *__dest, const void *__src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *memccpy (void *__restrict __dest, const void *__restrict __src,
int __c, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int memcmp (const void *__s1, const void *__s2, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *memchr (const void *__s, int __c, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern void *rawmemchr (const void *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern void *memrchr (const void *__s, int __c, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strncpy (char *__restrict __dest,
const char *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strncat (char *__restrict __dest, const char *__restrict __src,
size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strcmp (const char *__s1, const char *__s2)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strncmp (const char *__s1, const char *__s2, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strcoll (const char *__s1, const char *__s2)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern size_t strxfrm (char *__restrict __dest,
const char *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int strcoll_l (const char *__s1, const char *__s2, locale_t __l)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3)));
extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n,
locale_t __l) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 4)));
extern char *strdup (const char *__s)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1)));
extern char *strndup (const char *__string, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1)));
extern char *strchr (const char *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern char *strrchr (const char *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern char *strchrnul (const char *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern size_t strcspn (const char *__s, const char *__reject)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern size_t strspn (const char *__s, const char *__accept)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strpbrk (const char *__s, const char *__accept)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strstr (const char *__haystack, const char *__needle)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strtok (char *__restrict __s, const char *__restrict __delim)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern char *__strtok_r (char *__restrict __s,
const char *__restrict __delim,
char **__restrict __save_ptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern char *strtok_r (char *__restrict __s, const char *__restrict __delim,
char **__restrict __save_ptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern char *strcasestr (const char *__haystack, const char *__needle)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *memmem (const void *__haystack, size_t __haystacklen,
const void *__needle, size_t __needlelen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 3)));
extern void *__mempcpy (void *__restrict __dest,
const void *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void *mempcpy (void *__restrict __dest,
const void *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern size_t strlen (const char *__s)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern size_t strnlen (const char *__string, size_t __maxlen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern char *strerror (int __errnum) __attribute__ ((__nothrow__ , __leaf__));
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__));
extern char *strerror_l (int __errnum, locale_t __l) __attribute__ ((__nothrow__ , __leaf__));
extern int bcmp (const void *__s1, const void *__s2, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern void bcopy (const void *__src, void *__dest, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void bzero (void *__s, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern char *index (const char *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern char *rindex (const char *__s, int __c)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
extern int ffs (int __i) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int ffsl (long int __l) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
__extension__ extern int ffsll (long long int __ll)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int strcasecmp (const char *__s1, const char *__s2)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3)));
extern int strncasecmp_l (const char *__s1, const char *__s2,
size_t __n, locale_t __loc)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 4)));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void
__attribute__ ((__nothrow__ , __leaf__)) bcopy (const void *__src, void *__dest, size_t __len)
{
(void) __builtin___memmove_chk (__dest, __src, __len,
__builtin_object_size (__dest, 0));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void
__attribute__ ((__nothrow__ , __leaf__)) bzero (void *__dest, size_t __len)
{
(void) __builtin___memset_chk (__dest, '\0', __len,
__builtin_object_size (__dest, 0));
}
extern void explicit_bzero (void *__s, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern char *strsep (char **__restrict __stringp,
const char *__restrict __delim)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strsignal (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern char *__stpcpy (char *__restrict __dest, const char *__restrict __src)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpcpy (char *__restrict __dest, const char *__restrict __src)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *__stpncpy (char *__restrict __dest,
const char *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpncpy (char *__restrict __dest,
const char *__restrict __src, size_t __n)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int strverscmp (const char *__s1, const char *__s2)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *strfry (char *__string) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void *memfrob (void *__s, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern char *basename (const char *__filename) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void *
__attribute__ ((__nothrow__ , __leaf__)) memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
{
return __builtin___memcpy_chk (__dest, __src, __len,
__builtin_object_size (__dest, 0));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void *
__attribute__ ((__nothrow__ , __leaf__)) memmove (void *__dest, const void *__src, size_t __len)
{
return __builtin___memmove_chk (__dest, __src, __len,
__builtin_object_size (__dest, 0));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void *
__attribute__ ((__nothrow__ , __leaf__)) mempcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
{
return __builtin___mempcpy_chk (__dest, __src, __len,
__builtin_object_size (__dest, 0));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void *
__attribute__ ((__nothrow__ , __leaf__)) memset (void *__dest, int __ch, size_t __len)
{
return __builtin___memset_chk (__dest, __ch, __len,
__builtin_object_size (__dest, 0));
}
void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void
__attribute__ ((__nothrow__ , __leaf__)) explicit_bzero (void *__dest, size_t __len)
{
__explicit_bzero_chk (__dest, __len, __builtin_object_size (__dest, 0));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) strcpy (char *__restrict __dest, const char *__restrict __src)
{
return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) stpcpy (char *__restrict __dest, const char *__restrict __src)
{
return __builtin___stpcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) strncpy (char *__restrict __dest, const char *__restrict __src, size_t __len)
{
return __builtin___strncpy_chk (__dest, __src, __len,
__builtin_object_size (__dest, 2 > 1));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) stpncpy (char *__dest, const char *__src, size_t __n)
{
return __builtin___stpncpy_chk (__dest, __src, __n,
__builtin_object_size (__dest, 2 > 1));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) strcat (char *__restrict __dest, const char *__restrict __src)
{
return __builtin___strcat_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) char *
__attribute__ ((__nothrow__ , __leaf__)) strncat (char *__restrict __dest, const char *__restrict __src, size_t __len)
{
return __builtin___strncat_chk (__dest, __src, __len,
__builtin_object_size (__dest, 2 > 1));
}
typedef __uint8_t uint8_t;
typedef __uint16_t uint16_t;
typedef __uint32_t uint32_t;
typedef __uint64_t uint64_t;
typedef __int_least8_t int_least8_t;
typedef __int_least16_t int_least16_t;
typedef __int_least32_t int_least32_t;
typedef __int_least64_t int_least64_t;
typedef __uint_least8_t uint_least8_t;
typedef __uint_least16_t uint_least16_t;
typedef __uint_least32_t uint_least32_t;
typedef __uint_least64_t uint_least64_t;
typedef signed char int_fast8_t;
typedef long int int_fast16_t;
typedef long int int_fast32_t;
typedef long int int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned long int uint_fast16_t;
typedef unsigned long int uint_fast32_t;
typedef unsigned long int uint_fast64_t;
typedef long int intptr_t;
typedef unsigned long int uintptr_t;
typedef __intmax_t intmax_t;
typedef __uintmax_t uintmax_t;
typedef int __gwchar_t;
typedef struct
{
long int quot;
long int rem;
} imaxdiv_t;
extern intmax_t imaxabs (intmax_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern intmax_t strtoimax (const char *__restrict __nptr,
char **__restrict __endptr, int __base) __attribute__ ((__nothrow__ , __leaf__));
extern uintmax_t strtoumax (const char *__restrict __nptr,
char ** __restrict __endptr, int __base) __attribute__ ((__nothrow__ , __leaf__));
extern intmax_t wcstoimax (const __gwchar_t *__restrict __nptr,
__gwchar_t **__restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__));
extern uintmax_t wcstoumax (const __gwchar_t *__restrict __nptr,
__gwchar_t ** __restrict __endptr, int __base)
__attribute__ ((__nothrow__ , __leaf__));
extern long int __strtol_internal (const char *__restrict __nptr,
char **__restrict __endptr,
int __base, int __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__gnu_inline__)) intmax_t
__attribute__ ((__nothrow__ , __leaf__)) strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)
{
return __strtol_internal (nptr, endptr, base, 0);
}
extern unsigned long int __strtoul_internal (const char *__restrict __nptr,
char ** __restrict __endptr,
int __base, int __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__gnu_inline__)) uintmax_t
__attribute__ ((__nothrow__ , __leaf__)) strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)
{
return __strtoul_internal (nptr, endptr, base, 0);
}
extern long int __wcstol_internal (const __gwchar_t * __restrict __nptr,
__gwchar_t **__restrict __endptr,
int __base, int __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__gnu_inline__)) intmax_t
__attribute__ ((__nothrow__ , __leaf__)) wcstoimax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)
{
return __wcstol_internal (nptr, endptr, base, 0);
}
extern unsigned long int __wcstoul_internal (const __gwchar_t *
__restrict __nptr,
__gwchar_t **
__restrict __endptr,
int __base, int __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern __inline __attribute__ ((__gnu_inline__)) uintmax_t
__attribute__ ((__nothrow__ , __leaf__)) wcstoumax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)
{
return __wcstoul_internal (nptr, endptr, base, 0);
}
typedef __socklen_t socklen_t;
extern int access (const char *__name, int __type) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int euidaccess (const char *__name, int __type)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int eaccess (const char *__name, int __type)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int faccessat (int __fd, const char *__file, int __type, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__));
extern __off_t lseek (int __fd, __off_t __offset, int __whence) __attribute__ ((__nothrow__ , __leaf__));
extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence)
__attribute__ ((__nothrow__ , __leaf__));
extern int close (int __fd);
extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __attribute__ ((__warn_unused_result__));
extern ssize_t write (int __fd, const void *__buf, size_t __n) __attribute__ ((__warn_unused_result__));
extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
__off_t __offset) __attribute__ ((__warn_unused_result__));
extern ssize_t pwrite (int __fd, const void *__buf, size_t __n,
__off_t __offset) __attribute__ ((__warn_unused_result__));
extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
__off64_t __offset) __attribute__ ((__warn_unused_result__));
extern ssize_t pwrite64 (int __fd, const void *__buf, size_t __n,
__off64_t __offset) __attribute__ ((__warn_unused_result__));
extern int pipe (int __pipedes[2]) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int pipe2 (int __pipedes[2], int __flags) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern unsigned int alarm (unsigned int __seconds) __attribute__ ((__nothrow__ , __leaf__));
extern unsigned int sleep (unsigned int __seconds);
extern __useconds_t ualarm (__useconds_t __value, __useconds_t __interval)
__attribute__ ((__nothrow__ , __leaf__));
extern int usleep (__useconds_t __useconds);
extern int pause (void);
extern int chown (const char *__file, __uid_t __owner, __gid_t __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int fchown (int __fd, __uid_t __owner, __gid_t __group) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int lchown (const char *__file, __uid_t __owner, __gid_t __group)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int fchownat (int __fd, const char *__file, __uid_t __owner,
__gid_t __group, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__));
extern int chdir (const char *__path) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int fchdir (int __fd) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *getcwd (char *__buf, size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *get_current_dir_name (void) __attribute__ ((__nothrow__ , __leaf__));
extern char *getwd (char *__buf)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)) __attribute__ ((__warn_unused_result__));
extern int dup (int __fd) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int dup2 (int __fd, int __fd2) __attribute__ ((__nothrow__ , __leaf__));
extern int dup3 (int __fd, int __fd2, int __flags) __attribute__ ((__nothrow__ , __leaf__));
extern char **__environ;
extern char **environ;
extern int execve (const char *__path, char *const __argv[],
char *const __envp[]) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int fexecve (int __fd, char *const __argv[], char *const __envp[])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int execv (const char *__path, char *const __argv[])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int execle (const char *__path, const char *__arg, ...)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int execl (const char *__path, const char *__arg, ...)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int execvp (const char *__file, char *const __argv[])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int execlp (const char *__file, const char *__arg, ...)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int execvpe (const char *__file, char *const __argv[],
char *const __envp[])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int nice (int __inc) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void _exit (int __status) __attribute__ ((__noreturn__));
enum
{
_PC_LINK_MAX,
_PC_MAX_CANON,
_PC_MAX_INPUT,
_PC_NAME_MAX,
_PC_PATH_MAX,
_PC_PIPE_BUF,
_PC_CHOWN_RESTRICTED,
_PC_NO_TRUNC,
_PC_VDISABLE,
_PC_SYNC_IO,
_PC_ASYNC_IO,
_PC_PRIO_IO,
_PC_SOCK_MAXBUF,
_PC_FILESIZEBITS,
_PC_REC_INCR_XFER_SIZE,
_PC_REC_MAX_XFER_SIZE,
_PC_REC_MIN_XFER_SIZE,
_PC_REC_XFER_ALIGN,
_PC_ALLOC_SIZE_MIN,
_PC_SYMLINK_MAX,
_PC_2_SYMLINKS
};
enum
{
_SC_ARG_MAX,
_SC_CHILD_MAX,
_SC_CLK_TCK,
_SC_NGROUPS_MAX,
_SC_OPEN_MAX,
_SC_STREAM_MAX,
_SC_TZNAME_MAX,
_SC_JOB_CONTROL,
_SC_SAVED_IDS,
_SC_REALTIME_SIGNALS,
_SC_PRIORITY_SCHEDULING,
_SC_TIMERS,
_SC_ASYNCHRONOUS_IO,
_SC_PRIORITIZED_IO,
_SC_SYNCHRONIZED_IO,
_SC_FSYNC,
_SC_MAPPED_FILES,
_SC_MEMLOCK,
_SC_MEMLOCK_RANGE,
_SC_MEMORY_PROTECTION,
_SC_MESSAGE_PASSING,
_SC_SEMAPHORES,
_SC_SHARED_MEMORY_OBJECTS,
_SC_AIO_LISTIO_MAX,
_SC_AIO_MAX,
_SC_AIO_PRIO_DELTA_MAX,
_SC_DELAYTIMER_MAX,
_SC_MQ_OPEN_MAX,
_SC_MQ_PRIO_MAX,
_SC_VERSION,
_SC_PAGESIZE,
_SC_RTSIG_MAX,
_SC_SEM_NSEMS_MAX,
_SC_SEM_VALUE_MAX,
_SC_SIGQUEUE_MAX,
_SC_TIMER_MAX,
_SC_BC_BASE_MAX,
_SC_BC_DIM_MAX,
_SC_BC_SCALE_MAX,
_SC_BC_STRING_MAX,
_SC_COLL_WEIGHTS_MAX,
_SC_EQUIV_CLASS_MAX,
_SC_EXPR_NEST_MAX,
_SC_LINE_MAX,
_SC_RE_DUP_MAX,
_SC_CHARCLASS_NAME_MAX,
_SC_2_VERSION,
_SC_2_C_BIND,
_SC_2_C_DEV,
_SC_2_FORT_DEV,
_SC_2_FORT_RUN,
_SC_2_SW_DEV,
_SC_2_LOCALEDEF,
_SC_PII,
_SC_PII_XTI,
_SC_PII_SOCKET,
_SC_PII_INTERNET,
_SC_PII_OSI,
_SC_POLL,
_SC_SELECT,
_SC_UIO_MAXIOV,
_SC_IOV_MAX = _SC_UIO_MAXIOV,
_SC_PII_INTERNET_STREAM,
_SC_PII_INTERNET_DGRAM,
_SC_PII_OSI_COTS,
_SC_PII_OSI_CLTS,
_SC_PII_OSI_M,
_SC_T_IOV_MAX,
_SC_THREADS,
_SC_THREAD_SAFE_FUNCTIONS,
_SC_GETGR_R_SIZE_MAX,
_SC_GETPW_R_SIZE_MAX,
_SC_LOGIN_NAME_MAX,
_SC_TTY_NAME_MAX,
_SC_THREAD_DESTRUCTOR_ITERATIONS,
_SC_THREAD_KEYS_MAX,
_SC_THREAD_STACK_MIN,
_SC_THREAD_THREADS_MAX,
_SC_THREAD_ATTR_STACKADDR,
_SC_THREAD_ATTR_STACKSIZE,
_SC_THREAD_PRIORITY_SCHEDULING,
_SC_THREAD_PRIO_INHERIT,
_SC_THREAD_PRIO_PROTECT,
_SC_THREAD_PROCESS_SHARED,
_SC_NPROCESSORS_CONF,
_SC_NPROCESSORS_ONLN,
_SC_PHYS_PAGES,
_SC_AVPHYS_PAGES,
_SC_ATEXIT_MAX,
_SC_PASS_MAX,
_SC_XOPEN_VERSION,
_SC_XOPEN_XCU_VERSION,
_SC_XOPEN_UNIX,
_SC_XOPEN_CRYPT,
_SC_XOPEN_ENH_I18N,
_SC_XOPEN_SHM,
_SC_2_CHAR_TERM,
_SC_2_C_VERSION,
_SC_2_UPE,
_SC_XOPEN_XPG2,
_SC_XOPEN_XPG3,
_SC_XOPEN_XPG4,
_SC_CHAR_BIT,
_SC_CHAR_MAX,
_SC_CHAR_MIN,
_SC_INT_MAX,
_SC_INT_MIN,
_SC_LONG_BIT,
_SC_WORD_BIT,
_SC_MB_LEN_MAX,
_SC_NZERO,
_SC_SSIZE_MAX,
_SC_SCHAR_MAX,
_SC_SCHAR_MIN,
_SC_SHRT_MAX,
_SC_SHRT_MIN,
_SC_UCHAR_MAX,
_SC_UINT_MAX,
_SC_ULONG_MAX,
_SC_USHRT_MAX,
_SC_NL_ARGMAX,
_SC_NL_LANGMAX,
_SC_NL_MSGMAX,
_SC_NL_NMAX,
_SC_NL_SETMAX,
_SC_NL_TEXTMAX,
_SC_XBS5_ILP32_OFF32,
_SC_XBS5_ILP32_OFFBIG,
_SC_XBS5_LP64_OFF64,
_SC_XBS5_LPBIG_OFFBIG,
_SC_XOPEN_LEGACY,
_SC_XOPEN_REALTIME,
_SC_XOPEN_REALTIME_THREADS,
_SC_ADVISORY_INFO,
_SC_BARRIERS,
_SC_BASE,
_SC_C_LANG_SUPPORT,
_SC_C_LANG_SUPPORT_R,
_SC_CLOCK_SELECTION,
_SC_CPUTIME,
_SC_THREAD_CPUTIME,
_SC_DEVICE_IO,
_SC_DEVICE_SPECIFIC,
_SC_DEVICE_SPECIFIC_R,
_SC_FD_MGMT,
_SC_FIFO,
_SC_PIPE,
_SC_FILE_ATTRIBUTES,
_SC_FILE_LOCKING,
_SC_FILE_SYSTEM,
_SC_MONOTONIC_CLOCK,
_SC_MULTI_PROCESS,
_SC_SINGLE_PROCESS,
_SC_NETWORKING,
_SC_READER_WRITER_LOCKS,
_SC_SPIN_LOCKS,
_SC_REGEXP,
_SC_REGEX_VERSION,
_SC_SHELL,
_SC_SIGNALS,
_SC_SPAWN,
_SC_SPORADIC_SERVER,
_SC_THREAD_SPORADIC_SERVER,
_SC_SYSTEM_DATABASE,
_SC_SYSTEM_DATABASE_R,
_SC_TIMEOUTS,
_SC_TYPED_MEMORY_OBJECTS,
_SC_USER_GROUPS,
_SC_USER_GROUPS_R,
_SC_2_PBS,
_SC_2_PBS_ACCOUNTING,
_SC_2_PBS_LOCATE,
_SC_2_PBS_MESSAGE,
_SC_2_PBS_TRACK,
_SC_SYMLOOP_MAX,
_SC_STREAMS,
_SC_2_PBS_CHECKPOINT,
_SC_V6_ILP32_OFF32,
_SC_V6_ILP32_OFFBIG,
_SC_V6_LP64_OFF64,
_SC_V6_LPBIG_OFFBIG,
_SC_HOST_NAME_MAX,
_SC_TRACE,
_SC_TRACE_EVENT_FILTER,
_SC_TRACE_INHERIT,
_SC_TRACE_LOG,
_SC_LEVEL1_ICACHE_SIZE,
_SC_LEVEL1_ICACHE_ASSOC,
_SC_LEVEL1_ICACHE_LINESIZE,
_SC_LEVEL1_DCACHE_SIZE,
_SC_LEVEL1_DCACHE_ASSOC,
_SC_LEVEL1_DCACHE_LINESIZE,
_SC_LEVEL2_CACHE_SIZE,
_SC_LEVEL2_CACHE_ASSOC,
_SC_LEVEL2_CACHE_LINESIZE,
_SC_LEVEL3_CACHE_SIZE,
_SC_LEVEL3_CACHE_ASSOC,
_SC_LEVEL3_CACHE_LINESIZE,
_SC_LEVEL4_CACHE_SIZE,
_SC_LEVEL4_CACHE_ASSOC,
_SC_LEVEL4_CACHE_LINESIZE,
_SC_IPV6 = _SC_LEVEL1_ICACHE_SIZE + 50,
_SC_RAW_SOCKETS,
_SC_V7_ILP32_OFF32,
_SC_V7_ILP32_OFFBIG,
_SC_V7_LP64_OFF64,
_SC_V7_LPBIG_OFFBIG,
_SC_SS_REPL_MAX,
_SC_TRACE_EVENT_NAME_MAX,
_SC_TRACE_NAME_MAX,
_SC_TRACE_SYS_MAX,
_SC_TRACE_USER_EVENT_MAX,
_SC_XOPEN_STREAMS,
_SC_THREAD_ROBUST_PRIO_INHERIT,
_SC_THREAD_ROBUST_PRIO_PROTECT
};
enum
{
_CS_PATH,
_CS_V6_WIDTH_RESTRICTED_ENVS,
_CS_GNU_LIBC_VERSION,
_CS_GNU_LIBPTHREAD_VERSION,
_CS_V5_WIDTH_RESTRICTED_ENVS,
_CS_V7_WIDTH_RESTRICTED_ENVS,
_CS_LFS_CFLAGS = 1000,
_CS_LFS_LDFLAGS,
_CS_LFS_LIBS,
_CS_LFS_LINTFLAGS,
_CS_LFS64_CFLAGS,
_CS_LFS64_LDFLAGS,
_CS_LFS64_LIBS,
_CS_LFS64_LINTFLAGS,
_CS_XBS5_ILP32_OFF32_CFLAGS = 1100,
_CS_XBS5_ILP32_OFF32_LDFLAGS,
_CS_XBS5_ILP32_OFF32_LIBS,
_CS_XBS5_ILP32_OFF32_LINTFLAGS,
_CS_XBS5_ILP32_OFFBIG_CFLAGS,
_CS_XBS5_ILP32_OFFBIG_LDFLAGS,
_CS_XBS5_ILP32_OFFBIG_LIBS,
_CS_XBS5_ILP32_OFFBIG_LINTFLAGS,
_CS_XBS5_LP64_OFF64_CFLAGS,
_CS_XBS5_LP64_OFF64_LDFLAGS,
_CS_XBS5_LP64_OFF64_LIBS,
_CS_XBS5_LP64_OFF64_LINTFLAGS,
_CS_XBS5_LPBIG_OFFBIG_CFLAGS,
_CS_XBS5_LPBIG_OFFBIG_LDFLAGS,
_CS_XBS5_LPBIG_OFFBIG_LIBS,
_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,
_CS_POSIX_V6_ILP32_OFF32_CFLAGS,
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS,
_CS_POSIX_V6_ILP32_OFF32_LIBS,
_CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,
_CS_POSIX_V6_ILP32_OFFBIG_LIBS,
_CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,
_CS_POSIX_V6_LP64_OFF64_CFLAGS,
_CS_POSIX_V6_LP64_OFF64_LDFLAGS,
_CS_POSIX_V6_LP64_OFF64_LIBS,
_CS_POSIX_V6_LP64_OFF64_LINTFLAGS,
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS,
_CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS,
_CS_POSIX_V7_ILP32_OFF32_CFLAGS,
_CS_POSIX_V7_ILP32_OFF32_LDFLAGS,
_CS_POSIX_V7_ILP32_OFF32_LIBS,
_CS_POSIX_V7_ILP32_OFF32_LINTFLAGS,
_CS_POSIX_V7_ILP32_OFFBIG_CFLAGS,
_CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS,
_CS_POSIX_V7_ILP32_OFFBIG_LIBS,
_CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS,
_CS_POSIX_V7_LP64_OFF64_CFLAGS,
_CS_POSIX_V7_LP64_OFF64_LDFLAGS,
_CS_POSIX_V7_LP64_OFF64_LIBS,
_CS_POSIX_V7_LP64_OFF64_LINTFLAGS,
_CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS,
_CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS,
_CS_POSIX_V7_LPBIG_OFFBIG_LIBS,
_CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS,
_CS_V6_ENV,
_CS_V7_ENV
};
extern long int pathconf (const char *__path, int __name)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern long int fpathconf (int __fd, int __name) __attribute__ ((__nothrow__ , __leaf__));
extern long int sysconf (int __name) __attribute__ ((__nothrow__ , __leaf__));
extern size_t confstr (int __name, char *__buf, size_t __len) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t getpid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t getppid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t getpgrp (void) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t __getpgid (__pid_t __pid) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t getpgid (__pid_t __pid) __attribute__ ((__nothrow__ , __leaf__));
extern int setpgid (__pid_t __pid, __pid_t __pgid) __attribute__ ((__nothrow__ , __leaf__));
extern int setpgrp (void) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t setsid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __pid_t getsid (__pid_t __pid) __attribute__ ((__nothrow__ , __leaf__));
extern __uid_t getuid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __uid_t geteuid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __gid_t getgid (void) __attribute__ ((__nothrow__ , __leaf__));
extern __gid_t getegid (void) __attribute__ ((__nothrow__ , __leaf__));
extern int getgroups (int __size, __gid_t __list[]) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int group_member (__gid_t __gid) __attribute__ ((__nothrow__ , __leaf__));
extern int setuid (__uid_t __uid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int setreuid (__uid_t __ruid, __uid_t __euid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int seteuid (__uid_t __uid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int setgid (__gid_t __gid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int setregid (__gid_t __rgid, __gid_t __egid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int setegid (__gid_t __gid) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int getresuid (__uid_t *__ruid, __uid_t *__euid, __uid_t *__suid)
__attribute__ ((__nothrow__ , __leaf__));
extern int getresgid (__gid_t *__rgid, __gid_t *__egid, __gid_t *__sgid)
__attribute__ ((__nothrow__ , __leaf__));
extern int setresuid (__uid_t __ruid, __uid_t __euid, __uid_t __suid)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int setresgid (__gid_t __rgid, __gid_t __egid, __gid_t __sgid)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern __pid_t fork (void) __attribute__ ((__nothrow__));
extern __pid_t vfork (void) __attribute__ ((__nothrow__ , __leaf__));
extern char *ttyname (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern int ttyname_r (int __fd, char *__buf, size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2))) __attribute__ ((__warn_unused_result__));
extern int isatty (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern int ttyslot (void) __attribute__ ((__nothrow__ , __leaf__));
extern int link (const char *__from, const char *__to)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__));
extern int linkat (int __fromfd, const char *__from, int __tofd,
const char *__to, int __flags)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 4))) __attribute__ ((__warn_unused_result__));
extern int symlink (const char *__from, const char *__to)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__));
extern ssize_t readlink (const char *__restrict __path,
char *__restrict __buf, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__));
extern int symlinkat (const char *__from, int __tofd,
const char *__to) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3))) __attribute__ ((__warn_unused_result__));
extern ssize_t readlinkat (int __fd, const char *__restrict __path,
char *__restrict __buf, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3))) __attribute__ ((__warn_unused_result__));
extern int unlink (const char *__name) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int unlinkat (int __fd, const char *__name, int __flag)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int rmdir (const char *__path) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern __pid_t tcgetpgrp (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) __attribute__ ((__nothrow__ , __leaf__));
extern char *getlogin (void);
extern int getlogin_r (char *__name, size_t __name_len) __attribute__ ((__nonnull__ (1)));
extern int setlogin (const char *__name) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int gethostname (char *__name, size_t __len) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sethostname (const char *__name, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int sethostid (long int __id) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int getdomainname (char *__name, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int setdomainname (const char *__name, size_t __len)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int vhangup (void) __attribute__ ((__nothrow__ , __leaf__));
extern int revoke (const char *__file) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int profil (unsigned short int *__sample_buffer, size_t __size,
size_t __offset, unsigned int __scale)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int acct (const char *__name) __attribute__ ((__nothrow__ , __leaf__));
extern char *getusershell (void) __attribute__ ((__nothrow__ , __leaf__));
extern void endusershell (void) __attribute__ ((__nothrow__ , __leaf__));
extern void setusershell (void) __attribute__ ((__nothrow__ , __leaf__));
extern int daemon (int __nochdir, int __noclose) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int chroot (const char *__path) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern char *getpass (const char *__prompt) __attribute__ ((__nonnull__ (1)));
extern int fsync (int __fd);
extern int syncfs (int __fd) __attribute__ ((__nothrow__ , __leaf__));
extern long int gethostid (void);
extern void sync (void) __attribute__ ((__nothrow__ , __leaf__));
extern int getpagesize (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int getdtablesize (void) __attribute__ ((__nothrow__ , __leaf__));
extern int truncate (const char *__file, __off_t __length)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int truncate64 (const char *__file, __off64_t __length)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int ftruncate (int __fd, __off_t __length) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int ftruncate64 (int __fd, __off64_t __length) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int brk (void *__addr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void *sbrk (intptr_t __delta) __attribute__ ((__nothrow__ , __leaf__));
extern long int syscall (long int __sysno, ...) __attribute__ ((__nothrow__ , __leaf__));
extern int lockf (int __fd, int __cmd, __off_t __len) __attribute__ ((__warn_unused_result__));
extern int lockf64 (int __fd, int __cmd, __off64_t __len) __attribute__ ((__warn_unused_result__));
ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
int __outfd, __off64_t *__poutoff,
size_t __length, unsigned int __flags);
extern int fdatasync (int __fildes);
extern char *crypt (const char *__key, const char *__salt)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern void swab (const void *__restrict __from, void *__restrict __to,
ssize_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
int getentropy (void *__buffer, size_t __length) __attribute__ ((__warn_unused_result__));
extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
size_t __buflen) __attribute__ ((__warn_unused_result__));
extern ssize_t __read_alias (int __fd, void *__buf, size_t __nbytes) __asm__ ("" "read") __attribute__ ((__warn_unused_result__));
extern ssize_t __read_chk_warn (int __fd, void *__buf, size_t __nbytes, size_t __buflen) __asm__ ("" "__read_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("read called with bigger length than size of " "the destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) ssize_t
read (int __fd, void *__buf, size_t __nbytes)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 0)) && (__builtin_object_size (__buf, 0)) == (long unsigned int) -1) || (((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char))))) && (((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char)))))) ? __read_alias (__fd, __buf, __nbytes) : ((((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) && !(((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) ? __read_chk_warn (__fd, __buf, __nbytes, __builtin_object_size (__buf, 0)) : __read_chk (__fd, __buf, __nbytes, __builtin_object_size (__buf, 0))));
}
extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
__off_t __offset, size_t __bufsize) __attribute__ ((__warn_unused_result__));
extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes,
__off64_t __offset, size_t __bufsize) __attribute__ ((__warn_unused_result__));
extern ssize_t __pread_alias (int __fd, void *__buf, size_t __nbytes, __off_t __offset) __asm__ ("" "pread") __attribute__ ((__warn_unused_result__));
extern ssize_t __pread64_alias (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) __asm__ ("" "pread64") __attribute__ ((__warn_unused_result__));
extern ssize_t __pread_chk_warn (int __fd, void *__buf, size_t __nbytes, __off_t __offset, size_t __bufsize) __asm__ ("" "__pread_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("pread called with bigger length than size of " "the destination buffer")));
extern ssize_t __pread64_chk_warn (int __fd, void *__buf, size_t __nbytes, __off64_t __offset, size_t __bufsize) __asm__ ("" "__pread64_chk")
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("pread64 called with bigger length than size of " "the destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) ssize_t
pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 0)) && (__builtin_object_size (__buf, 0)) == (long unsigned int) -1) || (((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char))))) && (((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char)))))) ? __pread_alias (__fd, __buf, __nbytes, __offset) : ((((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) && !(((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) ? __pread_chk_warn (__fd, __buf, __nbytes, __offset, __builtin_object_size (__buf, 0)) : __pread_chk (__fd, __buf, __nbytes, __offset, __builtin_object_size (__buf, 0))));
}
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) ssize_t
pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 0)) && (__builtin_object_size (__buf, 0)) == (long unsigned int) -1) || (((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char))))) && (((long unsigned int) (__nbytes)) <= ((__builtin_object_size (__buf, 0))) / ((sizeof (char)))))) ? __pread64_alias (__fd, __buf, __nbytes, __offset) : ((((__typeof (__nbytes)) 0 < (__typeof (__nbytes)) -1 || (__builtin_constant_p (__nbytes) && (__nbytes) > 0)) && __builtin_constant_p ((((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) && !(((long unsigned int) (__nbytes)) <= (__builtin_object_size (__buf, 0)) / (sizeof (char)))) ? __pread64_chk_warn (__fd, __buf, __nbytes, __offset, __builtin_object_size (__buf, 0)) : __pread64_chk (__fd, __buf, __nbytes, __offset, __builtin_object_size (__buf, 0))));
}
extern ssize_t __readlink_chk (const char *__restrict __path,
char *__restrict __buf, size_t __len,
size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__));
extern ssize_t __readlink_alias (const char *__restrict __path, char *__restrict __buf, size_t __len) __asm__ ("" "readlink") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__));
extern ssize_t __readlink_chk_warn (const char *__restrict __path, char *__restrict __buf, size_t __len, size_t __buflen) __asm__ ("" "__readlink_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("readlink called with bigger length " "than size of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__warn_unused_result__)) ssize_t
__attribute__ ((__nothrow__ , __leaf__)) readlink (const char *__restrict __path, char *__restrict __buf, size_t __len)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __readlink_alias (__path, __buf, __len) : ((((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __readlink_chk_warn (__path, __buf, __len, __builtin_object_size (__buf, 2 > 1)) : __readlink_chk (__path, __buf, __len, __builtin_object_size (__buf, 2 > 1))));
}
extern ssize_t __readlinkat_chk (int __fd, const char *__restrict __path,
char *__restrict __buf, size_t __len,
size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3))) __attribute__ ((__warn_unused_result__));
extern ssize_t __readlinkat_alias (int __fd, const char *__restrict __path, char *__restrict __buf, size_t __len) __asm__ ("" "readlinkat") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2, 3))) __attribute__ ((__warn_unused_result__));
extern ssize_t __readlinkat_chk_warn (int __fd, const char *__restrict __path, char *__restrict __buf, size_t __len, size_t __buflen) __asm__ ("" "__readlinkat_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2, 3))) __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("readlinkat called with bigger " "length than size of destination " "buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__nonnull__ (2, 3))) __attribute__ ((__warn_unused_result__)) ssize_t
__attribute__ ((__nothrow__ , __leaf__)) readlinkat (int __fd, const char *__restrict __path, char *__restrict __buf, size_t __len)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __readlinkat_alias (__fd, __path, __buf, __len) : ((((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __readlinkat_chk_warn (__fd, __path, __buf, __len, __builtin_object_size (__buf, 2 > 1)) : __readlinkat_chk (__fd, __path, __buf, __len, __builtin_object_size (__buf, 2 > 1))));
}
extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *__getcwd_alias (char *__buf, size_t __size) __asm__ ("" "getcwd") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern char *__getcwd_chk_warn (char *__buf, size_t __size, size_t __buflen) __asm__ ("" "__getcwd_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("getcwd caller with bigger length than size of " "destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) char *
__attribute__ ((__nothrow__ , __leaf__)) getcwd (char *__buf, size_t __size)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__size)) 0 < (__typeof (__size)) -1 || (__builtin_constant_p (__size) && (__size) > 0)) && __builtin_constant_p ((((long unsigned int) (__size)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__size)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __getcwd_alias (__buf, __size) : ((((__typeof (__size)) 0 < (__typeof (__size)) -1 || (__builtin_constant_p (__size) && (__size) > 0)) && __builtin_constant_p ((((long unsigned int) (__size)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__size)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __getcwd_chk_warn (__buf, __size, __builtin_object_size (__buf, 2 > 1)) : __getcwd_chk (__buf, __size, __builtin_object_size (__buf, 2 > 1))));
}
extern char *__getwd_chk (char *__buf, size_t buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern char *__getwd_warn (char *__buf) __asm__ ("" "getwd") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("please use getcwd instead, as getwd " "doesn't specify buffer size")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__)) __attribute__ ((__warn_unused_result__)) char *
__attribute__ ((__nothrow__ , __leaf__)) getwd (char *__buf)
{
if (__builtin_object_size (__buf, 2 > 1) != (size_t) -1)
return __getwd_chk (__buf, __builtin_object_size (__buf, 2 > 1));
return __getwd_warn (__buf);
}
extern size_t __confstr_chk (int __name, char *__buf, size_t __len,
size_t __buflen) __attribute__ ((__nothrow__ , __leaf__));
extern size_t __confstr_alias (int __name, char *__buf, size_t __len) __asm__ ("" "confstr") __attribute__ ((__nothrow__ , __leaf__));
extern size_t __confstr_chk_warn (int __name, char *__buf, size_t __len, size_t __buflen) __asm__ ("" "__confstr_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__((__warning__ ("confstr called with bigger length than size of destination " "buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) size_t
__attribute__ ((__nothrow__ , __leaf__)) confstr (int __name, char *__buf, size_t __len)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__len)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __confstr_alias (__name, __buf, __len) : ((((__typeof (__len)) 0 < (__typeof (__len)) -1 || (__builtin_constant_p (__len) && (__len) > 0)) && __builtin_constant_p ((((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__len)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __confstr_chk_warn (__name, __buf, __len, __builtin_object_size (__buf, 2 > 1)) : __confstr_chk (__name, __buf, __len, __builtin_object_size (__buf, 2 > 1))));
}
extern int __getgroups_chk (int __size, __gid_t __list[], size_t __listlen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int __getgroups_alias (int __size, __gid_t __list[]) __asm__ ("" "getgroups") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern int __getgroups_chk_warn (int __size, __gid_t __list[], size_t __listlen) __asm__ ("" "__getgroups_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("getgroups called with bigger group count than what " "can fit into destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) getgroups (int __size, __gid_t __list[])
{
return (((__builtin_constant_p (__builtin_object_size (__list, 2 > 1)) && (__builtin_object_size (__list, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__size)) 0 < (__typeof (__size)) -1 || (__builtin_constant_p (__size) && (__size) > 0)) && __builtin_constant_p ((((long unsigned int) (__size)) <= ((__builtin_object_size (__list, 2 > 1))) / ((sizeof (__gid_t))))) && (((long unsigned int) (__size)) <= ((__builtin_object_size (__list, 2 > 1))) / ((sizeof (__gid_t)))))) ? __getgroups_alias (__size, __list) : ((((__typeof (__size)) 0 < (__typeof (__size)) -1 || (__builtin_constant_p (__size) && (__size) > 0)) && __builtin_constant_p ((((long unsigned int) (__size)) <= (__builtin_object_size (__list, 2 > 1)) / (sizeof (__gid_t)))) && !(((long unsigned int) (__size)) <= (__builtin_object_size (__list, 2 > 1)) / (sizeof (__gid_t)))) ? __getgroups_chk_warn (__size, __list, __builtin_object_size (__list, 2 > 1)) : __getgroups_chk (__size, __list, __builtin_object_size (__list, 2 > 1))));
}
extern int __ttyname_r_chk (int __fd, char *__buf, size_t __buflen,
size_t __nreal) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int __ttyname_r_alias (int __fd, char *__buf, size_t __buflen) __asm__ ("" "ttyname_r") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2)));
extern int __ttyname_r_chk_warn (int __fd, char *__buf, size_t __buflen, size_t __nreal) __asm__ ("" "__ttyname_r_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2))) __attribute__((__warning__ ("ttyname_r called with bigger buflen than " "size of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) ttyname_r (int __fd, char *__buf, size_t __buflen)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __ttyname_r_alias (__fd, __buf, __buflen) : ((((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __ttyname_r_chk_warn (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1)) : __ttyname_r_chk (__fd, __buf, __buflen, __builtin_object_size (__buf, 2 > 1))));
}
extern int __getlogin_r_chk (char *__buf, size_t __buflen, size_t __nreal)
__attribute__ ((__nonnull__ (1)));
extern int __getlogin_r_alias (char *__buf, size_t __buflen) __asm__ ("" "getlogin_r") __attribute__ ((__nonnull__ (1)));
extern int __getlogin_r_chk_warn (char *__buf, size_t __buflen, size_t __nreal) __asm__ ("" "__getlogin_r_chk")
__attribute__ ((__nonnull__ (1))) __attribute__((__warning__ ("getlogin_r called with bigger buflen than " "size of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
getlogin_r (char *__buf, size_t __buflen)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __getlogin_r_alias (__buf, __buflen) : ((((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __getlogin_r_chk_warn (__buf, __buflen, __builtin_object_size (__buf, 2 > 1)) : __getlogin_r_chk (__buf, __buflen, __builtin_object_size (__buf, 2 > 1))));
}
extern int __gethostname_chk (char *__buf, size_t __buflen, size_t __nreal)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int __gethostname_alias (char *__buf, size_t __buflen) __asm__ ("" "gethostname") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int __gethostname_chk_warn (char *__buf, size_t __buflen, size_t __nreal) __asm__ ("" "__gethostname_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1))) __attribute__((__warning__ ("gethostname called with bigger buflen than " "size of destination buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) gethostname (char *__buf, size_t __buflen)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __gethostname_alias (__buf, __buflen) : ((((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __gethostname_chk_warn (__buf, __buflen, __builtin_object_size (__buf, 2 > 1)) : __gethostname_chk (__buf, __buflen, __builtin_object_size (__buf, 2 > 1))));
}
extern int __getdomainname_chk (char *__buf, size_t __buflen, size_t __nreal)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int __getdomainname_alias (char *__buf, size_t __buflen) __asm__ ("" "getdomainname") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__));
extern int __getdomainname_chk_warn (char *__buf, size_t __buflen, size_t __nreal) __asm__ ("" "__getdomainname_chk") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1))) __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("getdomainname called with bigger " "buflen than size of destination " "buffer")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int
__attribute__ ((__nothrow__ , __leaf__)) getdomainname (char *__buf, size_t __buflen)
{
return (((__builtin_constant_p (__builtin_object_size (__buf, 2 > 1)) && (__builtin_object_size (__buf, 2 > 1)) == (long unsigned int) -1) || (((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char))))) && (((long unsigned int) (__buflen)) <= ((__builtin_object_size (__buf, 2 > 1))) / ((sizeof (char)))))) ? __getdomainname_alias (__buf, __buflen) : ((((__typeof (__buflen)) 0 < (__typeof (__buflen)) -1 || (__builtin_constant_p (__buflen) && (__buflen) > 0)) && __builtin_constant_p ((((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) && !(((long unsigned int) (__buflen)) <= (__builtin_object_size (__buf, 2 > 1)) / (sizeof (char)))) ? __getdomainname_chk_warn (__buf, __buflen, __builtin_object_size (__buf, 2 > 1)) : __getdomainname_chk (__buf, __buflen, __builtin_object_size (__buf, 2 > 1))));
}
__attribute__((__warn_unused_result__))
__attribute__((__malloc__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (1)))
void *ruby_xmalloc(size_t size)
;
__attribute__((__warn_unused_result__))
__attribute__((__malloc__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (1,2)))
void *ruby_xmalloc2(size_t nelems, size_t elemsiz)
;
__attribute__((__warn_unused_result__))
__attribute__((__malloc__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (1,2)))
void *ruby_xcalloc(size_t nelems, size_t elemsiz)
;
__attribute__((__warn_unused_result__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (2)))
void *ruby_xrealloc(void *ptr, size_t newsiz)
;
__attribute__((__warn_unused_result__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (2,3)))
void *ruby_xrealloc2(void *ptr, size_t newelems, size_t newsiz)
;
void ruby_xfree(void *ptr)
;
#define RBIMPL_ATTR_COLD_H
#define RBIMPL_ATTR_COLD() __attribute__((__cold__))
__attribute__((__noreturn__))
__attribute__((__cold__))
void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
#define COLDFUNC RBIMPL_ATTR_COLD()
typedef float float_t;
typedef double double_t;
enum
{
FP_INT_UPWARD =
0,
FP_INT_DOWNWARD =
1,
FP_INT_TOWARDZERO =
2,
FP_INT_TONEARESTFROMZERO =
3,
FP_INT_TONEAREST =
4,
};
extern int __fpclassify (double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __signbit (double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __isinf (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __finite (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __isnan (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __iseqsig (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern int __issignaling (double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern double acos (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __acos (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double asin (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __asin (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double atan (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __atan (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double atan2 (double __y, double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __atan2 (double __y, double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double cos (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __cos (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double sin (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __sin (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double tan (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __tan (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double cosh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __cosh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double sinh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __sinh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double tanh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __tanh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincos (double __x, double *__sinx, double *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincos (double __x, double *__sinx, double *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern double acosh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __acosh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double asinh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __asinh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double atanh (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __atanh (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double exp (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __exp (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double frexp (double __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern double __frexp (double __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern double ldexp (double __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern double __ldexp (double __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern double log (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __log (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double log10 (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __log10 (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double modf (double __x, double *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern double __modf (double __x, double *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern double exp10 (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __exp10 (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double expm1 (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __expm1 (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double log1p (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __log1p (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double logb (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __logb (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double exp2 (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __exp2 (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double log2 (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __log2 (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double pow (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __pow (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double sqrt (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __sqrt (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double hypot (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __hypot (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double cbrt (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __cbrt (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double ceil (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __ceil (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double fabs (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __fabs (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double floor (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __floor (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double fmod (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __fmod (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern int isinf (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int finite (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double drem (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __drem (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double significand (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __significand (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double copysign (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __copysign (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double nan (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern double __nan (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern int isnan (double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double j0 (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __j0 (double) __attribute__ ((__nothrow__ , __leaf__));
extern double j1 (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __j1 (double) __attribute__ ((__nothrow__ , __leaf__));
extern double jn (int, double) __attribute__ ((__nothrow__ , __leaf__)); extern double __jn (int, double) __attribute__ ((__nothrow__ , __leaf__));
extern double y0 (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __y0 (double) __attribute__ ((__nothrow__ , __leaf__));
extern double y1 (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __y1 (double) __attribute__ ((__nothrow__ , __leaf__));
extern double yn (int, double) __attribute__ ((__nothrow__ , __leaf__)); extern double __yn (int, double) __attribute__ ((__nothrow__ , __leaf__));
extern double erf (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __erf (double) __attribute__ ((__nothrow__ , __leaf__));
extern double erfc (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __erfc (double) __attribute__ ((__nothrow__ , __leaf__));
extern double lgamma (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __lgamma (double) __attribute__ ((__nothrow__ , __leaf__));
extern double tgamma (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __tgamma (double) __attribute__ ((__nothrow__ , __leaf__));
extern double gamma (double) __attribute__ ((__nothrow__ , __leaf__)); extern double __gamma (double) __attribute__ ((__nothrow__ , __leaf__));
extern double lgamma_r (double, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern double __lgamma_r (double, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern double rint (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __rint (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double nextafter (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __nextafter (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double nexttoward (double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __nexttoward (double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double nextdown (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __nextdown (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double nextup (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __nextup (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double remainder (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __remainder (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double scalbn (double __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern double __scalbn (double __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogb (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogb (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogb (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogb (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double scalbln (double __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern double __scalbln (double __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern double nearbyint (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern double __nearbyint (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double round (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __round (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double trunc (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __trunc (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double remquo (double __x, double __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern double __remquo (double __x, double __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrint (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrint (double __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrint (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrint (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lround (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lround (double __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llround (double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llround (double __x) __attribute__ ((__nothrow__ , __leaf__));
extern double fdim (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); extern double __fdim (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double fmax (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __fmax (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double fmin (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __fmin (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double fma (double __x, double __y, double __z) __attribute__ ((__nothrow__ , __leaf__)); extern double __fma (double __x, double __y, double __z) __attribute__ ((__nothrow__ , __leaf__));
extern double roundeven (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __roundeven (double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfp (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfp (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfp (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfp (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpx (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpx (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpx (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpx (double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern double fmaxmag (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __fmaxmag (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern double fminmag (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern double __fminmag (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorder (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermag (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalize (double *__cx, const double *__x) __attribute__ ((__nothrow__ , __leaf__));
extern double getpayload (const double *__x) __attribute__ ((__nothrow__ , __leaf__)); extern double __getpayload (const double *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayload (double *__x, double __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsig (double *__x, double __payload) __attribute__ ((__nothrow__ , __leaf__));
extern double scalb (double __x, double __n) __attribute__ ((__nothrow__ , __leaf__)); extern double __scalb (double __x, double __n) __attribute__ ((__nothrow__ , __leaf__));
extern int __fpclassifyf (float __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __signbitf (float __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __isinff (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __finitef (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __isnanf (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __iseqsigf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern int __issignalingf (float __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern float acosf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __acosf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float asinf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __asinf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float atanf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __atanf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float atan2f (float __y, float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __atan2f (float __y, float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float cosf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __cosf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float sinf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __sinf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float tanf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __tanf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float coshf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __coshf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float sinhf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __sinhf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float tanhf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __tanhf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf (float __x, float *__sinx, float *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf (float __x, float *__sinx, float *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern float acoshf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __acoshf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float asinhf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __asinhf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float atanhf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __atanhf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float expf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __expf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float frexpf (float __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern float __frexpf (float __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern float ldexpf (float __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern float __ldexpf (float __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern float logf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __logf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float log10f (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __log10f (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float modff (float __x, float *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern float __modff (float __x, float *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern float exp10f (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __exp10f (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float expm1f (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __expm1f (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float log1pf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __log1pf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float logbf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __logbf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float exp2f (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __exp2f (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float log2f (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __log2f (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float powf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __powf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float sqrtf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __sqrtf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float hypotf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __hypotf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float cbrtf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __cbrtf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float ceilf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __ceilf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float fabsf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __fabsf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float floorf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __floorf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float fmodf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __fmodf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern int isinff (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int finitef (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float dremf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __dremf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float significandf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __significandf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float copysignf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __copysignf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float nanf (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern float __nanf (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern int isnanf (float __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float j0f (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __j0f (float) __attribute__ ((__nothrow__ , __leaf__));
extern float j1f (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __j1f (float) __attribute__ ((__nothrow__ , __leaf__));
extern float jnf (int, float) __attribute__ ((__nothrow__ , __leaf__)); extern float __jnf (int, float) __attribute__ ((__nothrow__ , __leaf__));
extern float y0f (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __y0f (float) __attribute__ ((__nothrow__ , __leaf__));
extern float y1f (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __y1f (float) __attribute__ ((__nothrow__ , __leaf__));
extern float ynf (int, float) __attribute__ ((__nothrow__ , __leaf__)); extern float __ynf (int, float) __attribute__ ((__nothrow__ , __leaf__));
extern float erff (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __erff (float) __attribute__ ((__nothrow__ , __leaf__));
extern float erfcf (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __erfcf (float) __attribute__ ((__nothrow__ , __leaf__));
extern float lgammaf (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __lgammaf (float) __attribute__ ((__nothrow__ , __leaf__));
extern float tgammaf (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __tgammaf (float) __attribute__ ((__nothrow__ , __leaf__));
extern float gammaf (float) __attribute__ ((__nothrow__ , __leaf__)); extern float __gammaf (float) __attribute__ ((__nothrow__ , __leaf__));
extern float lgammaf_r (float, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern float __lgammaf_r (float, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern float rintf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __rintf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float nextafterf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __nextafterf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float nexttowardf (float __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __nexttowardf (float __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float nextdownf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __nextdownf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float nextupf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __nextupf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float remainderf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __remainderf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float scalbnf (float __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern float __scalbnf (float __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float scalblnf (float __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern float __scalblnf (float __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern float nearbyintf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern float __nearbyintf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float roundf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __roundf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float truncf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __truncf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float remquof (float __x, float __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern float __remquof (float __x, float __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf (float __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf (float __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf (float __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf (float __x) __attribute__ ((__nothrow__ , __leaf__));
extern float fdimf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)); extern float __fdimf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fmaxf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __fmaxf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float fminf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __fminf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float fmaf (float __x, float __y, float __z) __attribute__ ((__nothrow__ , __leaf__)); extern float __fmaf (float __x, float __y, float __z) __attribute__ ((__nothrow__ , __leaf__));
extern float roundevenf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __roundevenf (float __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf (float __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern float fmaxmagf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __fmaxmagf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern float fminmagf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern float __fminmagf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf (float __x, float __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef (float *__cx, const float *__x) __attribute__ ((__nothrow__ , __leaf__));
extern float getpayloadf (const float *__x) __attribute__ ((__nothrow__ , __leaf__)); extern float __getpayloadf (const float *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf (float *__x, float __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf (float *__x, float __payload) __attribute__ ((__nothrow__ , __leaf__));
extern float scalbf (float __x, float __n) __attribute__ ((__nothrow__ , __leaf__)); extern float __scalbf (float __x, float __n) __attribute__ ((__nothrow__ , __leaf__));
extern int __fpclassifyl (long double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __signbitl (long double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __isinfl (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __finitel (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __isnanl (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __iseqsigl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern int __issignalingl (long double __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern long double acosl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __acosl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double asinl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __asinl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double atanl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __atanl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double atan2l (long double __y, long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __atan2l (long double __y, long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double cosl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __cosl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double sinl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __sinl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double tanl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __tanl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double coshl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __coshl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double sinhl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __sinhl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double tanhl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __tanhl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosl (long double __x, long double *__sinx, long double *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosl (long double __x, long double *__sinx, long double *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern long double acoshl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __acoshl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double asinhl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __asinhl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double atanhl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __atanhl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double expl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __expl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double frexpl (long double __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern long double __frexpl (long double __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern long double ldexpl (long double __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern long double __ldexpl (long double __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern long double logl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __logl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double log10l (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __log10l (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double modfl (long double __x, long double *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern long double __modfl (long double __x, long double *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern long double exp10l (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __exp10l (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double expm1l (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __expm1l (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double log1pl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __log1pl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double logbl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __logbl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double exp2l (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __exp2l (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double log2l (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __log2l (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double powl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __powl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double sqrtl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __sqrtl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double hypotl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __hypotl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double cbrtl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __cbrtl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double ceill (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __ceill (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double fabsl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __fabsl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double floorl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __floorl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double fmodl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __fmodl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern int isinfl (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int finitel (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double dreml (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __dreml (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double significandl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __significandl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double copysignl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __copysignl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double nanl (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nanl (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern int isnanl (long double __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double j0l (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __j0l (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double j1l (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __j1l (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double jnl (int, long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __jnl (int, long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double y0l (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __y0l (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double y1l (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __y1l (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double ynl (int, long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __ynl (int, long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double erfl (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __erfl (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double erfcl (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __erfcl (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double lgammal (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __lgammal (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double tgammal (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __tgammal (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double gammal (long double) __attribute__ ((__nothrow__ , __leaf__)); extern long double __gammal (long double) __attribute__ ((__nothrow__ , __leaf__));
extern long double lgammal_r (long double, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern long double __lgammal_r (long double, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern long double rintl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __rintl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double nextafterl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nextafterl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double nexttowardl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nexttowardl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double nextdownl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nextdownl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double nextupl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nextupl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double remainderl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __remainderl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double scalbnl (long double __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern long double __scalbnl (long double __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double scalblnl (long double __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern long double __scalblnl (long double __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern long double nearbyintl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __nearbyintl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double roundl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __roundl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double truncl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __truncl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double remquol (long double __x, long double __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern long double __remquol (long double __x, long double __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundl (long double __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundl (long double __x) __attribute__ ((__nothrow__ , __leaf__));
extern long double fdiml (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)); extern long double __fdiml (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern long double fmaxl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __fmaxl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double fminl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __fminl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double fmal (long double __x, long double __y, long double __z) __attribute__ ((__nothrow__ , __leaf__)); extern long double __fmal (long double __x, long double __y, long double __z) __attribute__ ((__nothrow__ , __leaf__));
extern long double roundevenl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __roundevenl (long double __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxl (long double __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern long double fmaxmagl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __fmaxmagl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern long double fminmagl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern long double __fminmagl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizel (long double *__cx, const long double *__x) __attribute__ ((__nothrow__ , __leaf__));
extern long double getpayloadl (const long double *__x) __attribute__ ((__nothrow__ , __leaf__)); extern long double __getpayloadl (const long double *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadl (long double *__x, long double __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigl (long double *__x, long double __payload) __attribute__ ((__nothrow__ , __leaf__));
extern long double scalbl (long double __x, long double __n) __attribute__ ((__nothrow__ , __leaf__)); extern long double __scalbl (long double __x, long double __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 acosf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __acosf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 asinf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __asinf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 atanf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __atanf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 atan2f32 (_Float32 __y, _Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __atan2f32 (_Float32 __y, _Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 cosf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __cosf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 sinf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __sinf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 tanf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __tanf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 coshf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __coshf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 sinhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __sinhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 tanhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __tanhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf32 (_Float32 __x, _Float32 *__sinx, _Float32 *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf32 (_Float32 __x, _Float32 *__sinx, _Float32 *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 acoshf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __acoshf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 asinhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __asinhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 atanhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __atanhf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 expf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __expf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 frexpf32 (_Float32 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __frexpf32 (_Float32 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 ldexpf32 (_Float32 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __ldexpf32 (_Float32 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 logf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __logf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 log10f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __log10f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 modff32 (_Float32 __x, _Float32 *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __modff32 (_Float32 __x, _Float32 *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern _Float32 exp10f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __exp10f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 expm1f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __expm1f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 log1pf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __log1pf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 logbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __logbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 exp2f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __exp2f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 log2f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __log2f32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 powf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __powf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 sqrtf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __sqrtf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 hypotf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __hypotf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 cbrtf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __cbrtf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 ceilf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __ceilf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 fabsf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __fabsf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 floorf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __floorf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 fmodf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __fmodf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 copysignf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __copysignf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 nanf32 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __nanf32 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 j0f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __j0f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 j1f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __j1f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 jnf32 (int, _Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __jnf32 (int, _Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 y0f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __y0f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 y1f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __y1f32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 ynf32 (int, _Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __ynf32 (int, _Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 erff32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __erff32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 erfcf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __erfcf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 lgammaf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __lgammaf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 tgammaf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __tgammaf32 (_Float32) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 lgammaf32_r (_Float32, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __lgammaf32_r (_Float32, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 rintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __rintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 nextafterf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __nextafterf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 nextdownf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __nextdownf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 nextupf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __nextupf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 remainderf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __remainderf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 scalbnf32 (_Float32 __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __scalbnf32 (_Float32 __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 scalblnf32 (_Float32 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __scalblnf32 (_Float32 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 nearbyintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __nearbyintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 roundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __roundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 truncf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __truncf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 remquof32 (_Float32 __x, _Float32 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __remquof32 (_Float32 __x, _Float32 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 fdimf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __fdimf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 fmaxf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __fmaxf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 fminf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __fminf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 fmaf32 (_Float32 __x, _Float32 __y, _Float32 __z) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __fmaf32 (_Float32 __x, _Float32 __y, _Float32 __z) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 roundevenf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __roundevenf32 (_Float32 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf32 (_Float32 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 fmaxmagf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __fmaxmagf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32 fminmagf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32 __fminmagf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf32 (_Float32 __x, _Float32 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef32 (_Float32 *__cx, const _Float32 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 getpayloadf32 (const _Float32 *__x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32 __getpayloadf32 (const _Float32 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf32 (_Float32 *__x, _Float32 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf32 (_Float32 *__x, _Float32 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 acosf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __acosf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 asinf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __asinf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 atanf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __atanf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 atan2f64 (_Float64 __y, _Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __atan2f64 (_Float64 __y, _Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 cosf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __cosf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 sinf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __sinf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 tanf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __tanf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 coshf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __coshf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 sinhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __sinhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 tanhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __tanhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf64 (_Float64 __x, _Float64 *__sinx, _Float64 *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf64 (_Float64 __x, _Float64 *__sinx, _Float64 *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 acoshf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __acoshf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 asinhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __asinhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 atanhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __atanhf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 expf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __expf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 frexpf64 (_Float64 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __frexpf64 (_Float64 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 ldexpf64 (_Float64 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __ldexpf64 (_Float64 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 logf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __logf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 log10f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __log10f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 modff64 (_Float64 __x, _Float64 *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __modff64 (_Float64 __x, _Float64 *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern _Float64 exp10f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __exp10f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 expm1f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __expm1f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 log1pf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __log1pf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 logbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __logbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 exp2f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __exp2f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 log2f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __log2f64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 powf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __powf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 sqrtf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __sqrtf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 hypotf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __hypotf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 cbrtf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __cbrtf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 ceilf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __ceilf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 fabsf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __fabsf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 floorf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __floorf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 fmodf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __fmodf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 copysignf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __copysignf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 nanf64 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __nanf64 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 j0f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __j0f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 j1f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __j1f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 jnf64 (int, _Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __jnf64 (int, _Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 y0f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __y0f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 y1f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __y1f64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 ynf64 (int, _Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __ynf64 (int, _Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 erff64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __erff64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 erfcf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __erfcf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 lgammaf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __lgammaf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 tgammaf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __tgammaf64 (_Float64) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 lgammaf64_r (_Float64, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __lgammaf64_r (_Float64, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 rintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __rintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 nextafterf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __nextafterf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 nextdownf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __nextdownf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 nextupf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __nextupf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 remainderf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __remainderf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 scalbnf64 (_Float64 __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __scalbnf64 (_Float64 __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 scalblnf64 (_Float64 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __scalblnf64 (_Float64 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 nearbyintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __nearbyintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 roundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __roundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 truncf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __truncf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 remquof64 (_Float64 __x, _Float64 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __remquof64 (_Float64 __x, _Float64 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 fdimf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __fdimf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 fmaxf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __fmaxf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 fminf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __fminf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 fmaf64 (_Float64 __x, _Float64 __y, _Float64 __z) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __fmaf64 (_Float64 __x, _Float64 __y, _Float64 __z) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 roundevenf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __roundevenf64 (_Float64 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf64 (_Float64 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 fmaxmagf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __fmaxmagf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64 fminmagf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64 __fminmagf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef64 (_Float64 *__cx, const _Float64 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 getpayloadf64 (const _Float64 *__x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64 __getpayloadf64 (const _Float64 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf64 (_Float64 *__x, _Float64 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf64 (_Float64 *__x, _Float64 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int __fpclassifyf128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __signbitf128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int __isinff128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __finitef128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __isnanf128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int __iseqsigf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern int __issignalingf128 (_Float128 __value) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern _Float128 acosf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __acosf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 asinf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __asinf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 atanf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __atanf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 atan2f128 (_Float128 __y, _Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __atan2f128 (_Float128 __y, _Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 cosf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __cosf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 sinf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __sinf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 tanf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __tanf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 coshf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __coshf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 sinhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __sinhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 tanhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __tanhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf128 (_Float128 __x, _Float128 *__sinx, _Float128 *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf128 (_Float128 __x, _Float128 *__sinx, _Float128 *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 acoshf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __acoshf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 asinhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __asinhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 atanhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __atanhf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 expf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __expf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 frexpf128 (_Float128 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __frexpf128 (_Float128 __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 ldexpf128 (_Float128 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __ldexpf128 (_Float128 __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 logf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __logf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 log10f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __log10f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 modff128 (_Float128 __x, _Float128 *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __modff128 (_Float128 __x, _Float128 *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern _Float128 exp10f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __exp10f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 expm1f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __expm1f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 log1pf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __log1pf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 logbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __logbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 exp2f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __exp2f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 log2f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __log2f128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 powf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __powf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 sqrtf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __sqrtf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 hypotf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __hypotf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 cbrtf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __cbrtf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 ceilf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __ceilf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 fabsf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __fabsf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 floorf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __floorf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 fmodf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __fmodf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 copysignf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __copysignf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 nanf128 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __nanf128 (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 j0f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __j0f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 j1f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __j1f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 jnf128 (int, _Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __jnf128 (int, _Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 y0f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __y0f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 y1f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __y1f128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 ynf128 (int, _Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __ynf128 (int, _Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 erff128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __erff128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 erfcf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __erfcf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 lgammaf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __lgammaf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 tgammaf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __tgammaf128 (_Float128) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 lgammaf128_r (_Float128, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __lgammaf128_r (_Float128, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 rintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __rintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 nextafterf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __nextafterf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 nextdownf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __nextdownf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 nextupf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __nextupf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 remainderf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __remainderf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 scalbnf128 (_Float128 __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __scalbnf128 (_Float128 __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 scalblnf128 (_Float128 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __scalblnf128 (_Float128 __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 nearbyintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __nearbyintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 roundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __roundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 truncf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __truncf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 remquof128 (_Float128 __x, _Float128 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __remquof128 (_Float128 __x, _Float128 __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 fdimf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __fdimf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 fmaxf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __fmaxf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 fminf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __fminf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 fmaf128 (_Float128 __x, _Float128 __y, _Float128 __z) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __fmaf128 (_Float128 __x, _Float128 __y, _Float128 __z) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 roundevenf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __roundevenf128 (_Float128 __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf128 (_Float128 __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 fmaxmagf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __fmaxmagf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float128 fminmagf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float128 __fminmagf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef128 (_Float128 *__cx, const _Float128 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float128 getpayloadf128 (const _Float128 *__x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float128 __getpayloadf128 (const _Float128 *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf128 (_Float128 *__x, _Float128 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf128 (_Float128 *__x, _Float128 __payload) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x acosf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __acosf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x asinf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __asinf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x atanf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __atanf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x atan2f32x (_Float32x __y, _Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __atan2f32x (_Float32x __y, _Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x cosf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __cosf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x sinf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __sinf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x tanf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __tanf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x coshf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __coshf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x sinhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __sinhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x tanhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __tanhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf32x (_Float32x __x, _Float32x *__sinx, _Float32x *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf32x (_Float32x __x, _Float32x *__sinx, _Float32x *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x acoshf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __acoshf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x asinhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __asinhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x atanhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __atanhf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x expf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __expf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x frexpf32x (_Float32x __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __frexpf32x (_Float32x __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x ldexpf32x (_Float32x __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __ldexpf32x (_Float32x __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x logf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __logf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x log10f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __log10f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x modff32x (_Float32x __x, _Float32x *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __modff32x (_Float32x __x, _Float32x *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern _Float32x exp10f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __exp10f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x expm1f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __expm1f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x log1pf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __log1pf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x logbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __logbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x exp2f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __exp2f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x log2f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __log2f32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x powf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __powf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x sqrtf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __sqrtf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x hypotf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __hypotf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x cbrtf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __cbrtf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x ceilf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __ceilf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x fabsf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __fabsf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x floorf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __floorf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x fmodf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __fmodf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x copysignf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __copysignf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x nanf32x (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __nanf32x (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x j0f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __j0f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x j1f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __j1f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x jnf32x (int, _Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __jnf32x (int, _Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x y0f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __y0f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x y1f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __y1f32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x ynf32x (int, _Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __ynf32x (int, _Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x erff32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __erff32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x erfcf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __erfcf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x lgammaf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __lgammaf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x tgammaf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __tgammaf32x (_Float32x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x lgammaf32x_r (_Float32x, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __lgammaf32x_r (_Float32x, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x rintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __rintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x nextafterf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __nextafterf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x nextdownf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __nextdownf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x nextupf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __nextupf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x remainderf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __remainderf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x scalbnf32x (_Float32x __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __scalbnf32x (_Float32x __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x scalblnf32x (_Float32x __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __scalblnf32x (_Float32x __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x nearbyintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __nearbyintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x roundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __roundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x truncf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __truncf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x remquof32x (_Float32x __x, _Float32x __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __remquof32x (_Float32x __x, _Float32x __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x fdimf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __fdimf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x fmaxf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __fmaxf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x fminf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __fminf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x fmaf32x (_Float32x __x, _Float32x __y, _Float32x __z) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __fmaf32x (_Float32x __x, _Float32x __y, _Float32x __z) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x roundevenf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __roundevenf32x (_Float32x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf32x (_Float32x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x fmaxmagf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __fmaxmagf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float32x fminmagf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float32x __fminmagf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef32x (_Float32x *__cx, const _Float32x *__x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x getpayloadf32x (const _Float32x *__x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float32x __getpayloadf32x (const _Float32x *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf32x (_Float32x *__x, _Float32x __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf32x (_Float32x *__x, _Float32x __payload) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x acosf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __acosf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x asinf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __asinf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x atanf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __atanf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x atan2f64x (_Float64x __y, _Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __atan2f64x (_Float64x __y, _Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x cosf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __cosf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x sinf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __sinf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x tanf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __tanf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x coshf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __coshf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x sinhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __sinhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x tanhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __tanhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern void sincosf64x (_Float64x __x, _Float64x *__sinx, _Float64x *__cosx) __attribute__ ((__nothrow__ , __leaf__)); extern void __sincosf64x (_Float64x __x, _Float64x *__sinx, _Float64x *__cosx) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x acoshf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __acoshf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x asinhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __asinhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x atanhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __atanhf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x expf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __expf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x frexpf64x (_Float64x __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __frexpf64x (_Float64x __x, int *__exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x ldexpf64x (_Float64x __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __ldexpf64x (_Float64x __x, int __exponent) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x logf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __logf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x log10f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __log10f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x modff64x (_Float64x __x, _Float64x *__iptr) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __modff64x (_Float64x __x, _Float64x *__iptr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern _Float64x exp10f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __exp10f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x expm1f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __expm1f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x log1pf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __log1pf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x logbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __logbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x exp2f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __exp2f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x log2f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __log2f64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x powf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __powf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x sqrtf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __sqrtf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x hypotf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __hypotf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x cbrtf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __cbrtf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x ceilf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __ceilf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x fabsf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __fabsf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x floorf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __floorf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x fmodf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __fmodf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x copysignf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __copysignf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x nanf64x (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __nanf64x (const char *__tagb) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x j0f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __j0f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x j1f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __j1f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x jnf64x (int, _Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __jnf64x (int, _Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x y0f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __y0f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x y1f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __y1f64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x ynf64x (int, _Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __ynf64x (int, _Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x erff64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __erff64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x erfcf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __erfcf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x lgammaf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __lgammaf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x tgammaf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __tgammaf64x (_Float64x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x lgammaf64x_r (_Float64x, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __lgammaf64x_r (_Float64x, int *__signgamp) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x rintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __rintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x nextafterf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __nextafterf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x nextdownf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __nextdownf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x nextupf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __nextupf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x remainderf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __remainderf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x scalbnf64x (_Float64x __x, int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __scalbnf64x (_Float64x __x, int __n) __attribute__ ((__nothrow__ , __leaf__));
extern int ilogbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern int __ilogbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int llogbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __llogbf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x scalblnf64x (_Float64x __x, long int __n) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __scalblnf64x (_Float64x __x, long int __n) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x nearbyintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __nearbyintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x roundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __roundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x truncf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __truncf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x remquof64x (_Float64x __x, _Float64x __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __remquof64x (_Float64x __x, _Float64x __y, int *__quo) __attribute__ ((__nothrow__ , __leaf__));
extern long int lrintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lrintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llrintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llrintf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern long int lroundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long int __lroundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
__extension__
extern long long int llroundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)); extern long long int __llroundf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x fdimf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __fdimf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x fmaxf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __fmaxf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x fminf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __fminf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x fmaf64x (_Float64x __x, _Float64x __y, _Float64x __z) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __fmaf64x (_Float64x __x, _Float64x __y, _Float64x __z) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x roundevenf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __roundevenf64x (_Float64x __x) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern __intmax_t fromfpf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __intmax_t fromfpxf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __intmax_t __fromfpxf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern __uintmax_t ufromfpxf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__)); extern __uintmax_t __ufromfpxf64x (_Float64x __x, int __round, unsigned int __width) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x fmaxmagf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __fmaxmagf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern _Float64x fminmagf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__)); extern _Float64x __fminmagf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int totalorderf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int totalordermagf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__const__));
extern int canonicalizef64x (_Float64x *__cx, const _Float64x *__x) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x getpayloadf64x (const _Float64x *__x) __attribute__ ((__nothrow__ , __leaf__)); extern _Float64x __getpayloadf64x (const _Float64x *__x) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadf64x (_Float64x *__x, _Float64x __payload) __attribute__ ((__nothrow__ , __leaf__));
extern int setpayloadsigf64x (_Float64x *__x, _Float64x __payload) __attribute__ ((__nothrow__ , __leaf__));
extern float fadd (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fdiv (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fmul (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fsub (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float faddl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fdivl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fmull (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern float fsubl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double daddl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double ddivl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double dmull (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern double dsubl (long double __x, long double __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32addf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32divf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32mulf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32subf32x (_Float32x __x, _Float32x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32addf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32divf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32mulf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32subf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32addf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32divf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32mulf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32subf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32addf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32divf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32mulf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32 f32subf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xaddf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xdivf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xmulf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xsubf64 (_Float64 __x, _Float64 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xaddf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xdivf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xmulf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xsubf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xaddf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xdivf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xmulf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float32x f32xsubf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64addf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64divf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64mulf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64subf64x (_Float64x __x, _Float64x __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64addf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64divf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64mulf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64 f64subf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x f64xaddf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x f64xdivf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x f64xmulf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern _Float64x f64xsubf128 (_Float128 __x, _Float128 __y) __attribute__ ((__nothrow__ , __leaf__));
extern int signgam;
enum
{
FP_NAN =
0,
FP_INFINITE =
1,
FP_ZERO =
2,
FP_SUBNORMAL =
3,
FP_NORMAL =
4
};
extern int __iscanonicall (long double __x)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
struct timex
{
unsigned int modes;
__syscall_slong_t offset;
__syscall_slong_t freq;
__syscall_slong_t maxerror;
__syscall_slong_t esterror;
int status;
__syscall_slong_t constant;
__syscall_slong_t precision;
__syscall_slong_t tolerance;
struct timeval time;
__syscall_slong_t tick;
__syscall_slong_t ppsfreq;
__syscall_slong_t jitter;
int shift;
__syscall_slong_t stabil;
__syscall_slong_t jitcnt;
__syscall_slong_t calcnt;
__syscall_slong_t errcnt;
__syscall_slong_t stbcnt;
int tai;
int :32; int :32; int :32; int :32;
int :32; int :32; int :32; int :32;
int :32; int :32; int :32;
};
extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) __attribute__ ((__nothrow__ , __leaf__));
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
long int tm_gmtoff;
const char *tm_zone;
};
struct itimerspec
{
struct timespec it_interval;
struct timespec it_value;
};
struct sigevent;
extern clock_t clock (void) __attribute__ ((__nothrow__ , __leaf__));
extern time_t time (time_t *__timer) __attribute__ ((__nothrow__ , __leaf__));
extern double difftime (time_t __time1, time_t __time0)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern time_t mktime (struct tm *__tp) __attribute__ ((__nothrow__ , __leaf__));
extern size_t strftime (char *__restrict __s, size_t __maxsize,
const char *__restrict __format,
const struct tm *__restrict __tp) __attribute__ ((__nothrow__ , __leaf__));
extern char *strptime (const char *__restrict __s,
const char *__restrict __fmt, struct tm *__tp)
__attribute__ ((__nothrow__ , __leaf__));
extern size_t strftime_l (char *__restrict __s, size_t __maxsize,
const char *__restrict __format,
const struct tm *__restrict __tp,
locale_t __loc) __attribute__ ((__nothrow__ , __leaf__));
extern char *strptime_l (const char *__restrict __s,
const char *__restrict __fmt, struct tm *__tp,
locale_t __loc) __attribute__ ((__nothrow__ , __leaf__));
extern struct tm *gmtime (const time_t *__timer) __attribute__ ((__nothrow__ , __leaf__));
extern struct tm *localtime (const time_t *__timer) __attribute__ ((__nothrow__ , __leaf__));
extern struct tm *gmtime_r (const time_t *__restrict __timer,
struct tm *__restrict __tp) __attribute__ ((__nothrow__ , __leaf__));
extern struct tm *localtime_r (const time_t *__restrict __timer,
struct tm *__restrict __tp) __attribute__ ((__nothrow__ , __leaf__));
extern char *asctime (const struct tm *__tp) __attribute__ ((__nothrow__ , __leaf__));
extern char *ctime (const time_t *__timer) __attribute__ ((__nothrow__ , __leaf__));
extern char *asctime_r (const struct tm *__restrict __tp,
char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
extern char *ctime_r (const time_t *__restrict __timer,
char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
extern char *__tzname[2];
extern int __daylight;
extern long int __timezone;
extern char *tzname[2];
extern void tzset (void) __attribute__ ((__nothrow__ , __leaf__));
extern int daylight;
extern long int timezone;
extern int stime (const time_t *__when) __attribute__ ((__nothrow__ , __leaf__));
extern time_t timegm (struct tm *__tp) __attribute__ ((__nothrow__ , __leaf__));
extern time_t timelocal (struct tm *__tp) __attribute__ ((__nothrow__ , __leaf__));
extern int dysize (int __year) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int nanosleep (const struct timespec *__requested_time,
struct timespec *__remaining);
extern int clock_getres (clockid_t __clock_id, struct timespec *__res) __attribute__ ((__nothrow__ , __leaf__));
extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __attribute__ ((__nothrow__ , __leaf__));
extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp)
__attribute__ ((__nothrow__ , __leaf__));
extern int clock_nanosleep (clockid_t __clock_id, int __flags,
const struct timespec *__req,
struct timespec *__rem);
extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) __attribute__ ((__nothrow__ , __leaf__));
extern int timer_create (clockid_t __clock_id,
struct sigevent *__restrict __evp,
timer_t *__restrict __timerid) __attribute__ ((__nothrow__ , __leaf__));
extern int timer_delete (timer_t __timerid) __attribute__ ((__nothrow__ , __leaf__));
extern int timer_settime (timer_t __timerid, int __flags,
const struct itimerspec *__restrict __value,
struct itimerspec *__restrict __ovalue) __attribute__ ((__nothrow__ , __leaf__));
extern int timer_gettime (timer_t __timerid, struct itimerspec *__value)
__attribute__ ((__nothrow__ , __leaf__));
extern int timer_getoverrun (timer_t __timerid) __attribute__ ((__nothrow__ , __leaf__));
extern int timespec_get (struct timespec *__ts, int __base)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int getdate_err;
extern struct tm *getdate (const char *__string);
extern int getdate_r (const char *__restrict __string,
struct tm *__restrict __resbufp);
struct timezone
{
int tz_minuteswest;
int tz_dsttime;
};
typedef struct timezone *__restrict __timezone_ptr_t;
extern int gettimeofday (struct timeval *__restrict __tv,
__timezone_ptr_t __tz) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int settimeofday (const struct timeval *__tv,
const struct timezone *__tz)
__attribute__ ((__nothrow__ , __leaf__));
extern int adjtime (const struct timeval *__delta,
struct timeval *__olddelta) __attribute__ ((__nothrow__ , __leaf__));
enum __itimer_which
{
ITIMER_REAL = 0,
ITIMER_VIRTUAL = 1,
ITIMER_PROF = 2
};
struct itimerval
{
struct timeval it_interval;
struct timeval it_value;
};
typedef enum __itimer_which __itimer_which_t;
extern int getitimer (__itimer_which_t __which,
struct itimerval *__value) __attribute__ ((__nothrow__ , __leaf__));
extern int setitimer (__itimer_which_t __which,
const struct itimerval *__restrict __new,
struct itimerval *__restrict __old) __attribute__ ((__nothrow__ , __leaf__));
extern int utimes (const char *__file, const struct timeval __tvp[2])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int lutimes (const char *__file, const struct timeval __tvp[2])
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int futimes (int __fd, const struct timeval __tvp[2]) __attribute__ ((__nothrow__ , __leaf__));
extern int futimesat (int __fd, const char *__file,
const struct timeval __tvp[2]) __attribute__ ((__nothrow__ , __leaf__));
extern size_t strlcpy(char *, const char*, size_t);
extern size_t strlcat(char *, const char*, size_t);
__attribute__((__format__(__printf__, 1, 2)))
extern void setproctitle(const char *fmt, ...);
typedef unsigned long VALUE;
typedef unsigned long ID;
__extension__ _Static_assert(4 == sizeof(int), "sizeof_int" ": " "SIZEOF_INT == sizeof(int)");
__extension__ _Static_assert(8 == sizeof(long), "sizeof_long" ": " "SIZEOF_LONG == sizeof(long)");
__extension__ _Static_assert(8 == sizeof(long long), "sizeof_long_long" ": " "SIZEOF_LONG_LONG == sizeof(LONG_LONG)");
__extension__ _Static_assert(8 == sizeof(void *), "sizeof_voidp" ": " "SIZEOF_VOIDP == sizeof(void *)");
VALUE rb_class_new(VALUE super);
VALUE rb_mod_init_copy(VALUE clone, VALUE orig);
void rb_check_inheritable(VALUE super);
VALUE rb_define_class_id(ID id, VALUE super);
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super);
VALUE rb_module_new(void);
VALUE rb_refinement_new(void);
VALUE rb_define_module_id(ID id);
VALUE rb_define_module_id_under(VALUE outer, ID id);
VALUE rb_mod_included_modules(VALUE mod);
VALUE rb_mod_include_p(VALUE child, VALUE parent);
VALUE rb_mod_ancestors(VALUE mod);
VALUE rb_class_descendants(VALUE klass);
VALUE rb_class_subclasses(VALUE klass);
VALUE rb_class_attached_object(VALUE klass);
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod);
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod);
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod);
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod);
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj);
void rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(), int arity);
void rb_undef(VALUE mod, ID mid);
__attribute__((__nonnull__ ()))
void rb_define_protected_method(VALUE klass, const char *mid, VALUE (*func)(), int arity);
__attribute__((__nonnull__ ()))
void rb_define_private_method(VALUE klass, const char *mid, VALUE (*func)(), int arity);
__attribute__((__nonnull__ ()))
void rb_define_singleton_method(VALUE obj, const char *mid, VALUE(*func)(), int arity);
VALUE rb_singleton_class(VALUE obj);
int rb_sourceline(void);
const char *rb_sourcefile(void);
int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv);
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat);
VALUE rb_apply(VALUE recv, ID mid, VALUE args);
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE recv);
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE recv);
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod);
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod);
typedef VALUE (*rb_alloc_func_t)(VALUE klass);
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func);
void rb_undef_alloc_func(VALUE klass);
rb_alloc_func_t rb_get_alloc_func(VALUE klass);
void rb_clear_constant_cache_for_id(ID id);
void rb_alias(VALUE klass, ID dst, ID src);
void rb_attr(VALUE klass, ID name, int need_reader, int need_writer, int honour_visibility);
__attribute__((__nonnull__ ()))
void rb_remove_method(VALUE klass, const char *name);
void rb_remove_method_id(VALUE klass, ID mid);
int rb_method_boundp(VALUE klass, ID id, int ex);
int rb_method_basic_definition_p(VALUE klass, ID mid);
int rb_obj_respond_to(VALUE obj, ID mid, int private_p);
int rb_respond_to(VALUE obj, ID mid);
__attribute__((__noreturn__))
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker);
void rb_backtrace(void);
VALUE rb_make_backtrace(void);
__attribute__((__nonnull__ ()))
void rb_define_method(VALUE klass, const char *mid, VALUE (*func)(), int arity);
__attribute__((__nonnull__ ()))
void rb_define_module_function(VALUE klass, const char *mid, VALUE (*func)(), int arity);
__attribute__((__nonnull__ ()))
void rb_define_global_function(const char *mid, VALUE (*func)(), int arity);
__attribute__((__nonnull__ ()))
void rb_undef_method(VALUE klass, const char *name);
__attribute__((__nonnull__ ()))
void rb_define_alias(VALUE klass, const char *dst, const char *src);
__attribute__((__nonnull__ ()))
void rb_define_attr(VALUE klass, const char *name, int read, int write);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_notimpl(VALUE, const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_m3(VALUE, const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_m2(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_m1(VALUE, const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_00(VALUE, const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_01(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_02(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_03(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_04(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_05(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_06(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_07(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_08(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_09(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_10(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_11(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_12(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_13(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_14(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_singleton_method"))) static void rb_define_singleton_method_15(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_notimpl(VALUE, const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_m3(VALUE, const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_m2(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_m1(VALUE, const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_00(VALUE, const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_01(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_02(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_03(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_04(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_05(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_06(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_07(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_08(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_09(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_10(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_11(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_12(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_13(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_14(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_protected_method"))) static void rb_define_protected_method_15(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_notimpl(VALUE, const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_m3(VALUE, const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_m2(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_m1(VALUE, const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_00(VALUE, const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_01(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_02(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_03(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_04(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_05(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_06(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_07(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_08(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_09(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_10(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_11(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_12(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_13(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_14(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_private_method"))) static void rb_define_private_method_15(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_notimpl(VALUE, const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_m3(VALUE, const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_m2(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_m1(VALUE, const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_00(VALUE, const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_01(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_02(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_03(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_04(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_05(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_06(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_07(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_08(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_09(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_10(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_11(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_12(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_13(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_14(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_module_function"))) static void rb_define_module_function_15(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_notimpl(const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_m3(const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_m2(const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_m1(const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_00(const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_01(const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_02(const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_03(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_04(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_05(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_06(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_07(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_08(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_09(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_10(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_11(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_12(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_13(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_14(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_global_function"))) static void rb_define_global_function_15(const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_notimpl(VALUE, ID, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_m3(VALUE, ID, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_m2(VALUE, ID, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_m1(VALUE, ID, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_00(VALUE, ID, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_01(VALUE, ID, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_02(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_03(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_04(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_05(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_06(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_07(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_08(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_09(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_10(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_11(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_12(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_13(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_14(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method_id"))) static void rb_define_method_id_15(VALUE, ID, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
__attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_notimpl(VALUE, const char *, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_m3(VALUE, const char *, VALUE(*)(), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_m2(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_m1(VALUE, const char *, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_00(VALUE, const char *, VALUE(*)(VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_01(VALUE, const char *, VALUE(*)(VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_02(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_03(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_04(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_05(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_06(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_07(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_08(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_09(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_10(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_11(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_12(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_13(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_14(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); __attribute__((__unused__)) __attribute__((__nonnull__ ())) __attribute__((__weakref__("rb_define_method"))) static void rb_define_method_15(VALUE, const char *, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
VALUE rb_int2big(intptr_t i);
VALUE rb_int2inum(intptr_t i);
VALUE rb_uint2big(uintptr_t i);
VALUE rb_uint2inum(uintptr_t i);
enum
ruby_special_consts {
RUBY_Qfalse = 0x00,
RUBY_Qnil = 0x04,
RUBY_Qtrue = 0x14,
RUBY_Qundef = 0x24,
RUBY_IMMEDIATE_MASK = 0x07,
RUBY_FIXNUM_FLAG = 0x01,
RUBY_FLONUM_MASK = 0x03,
RUBY_FLONUM_FLAG = 0x02,
RUBY_SYMBOL_FLAG = 0x0c,
RUBY_SPECIAL_SHIFT = 8
};
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_TEST(VALUE obj)
{
return obj & ~RUBY_Qnil;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_NIL_P(VALUE obj)
{
return obj == RUBY_Qnil;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_UNDEF_P(VALUE obj)
{
return obj == RUBY_Qundef;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_NIL_OR_UNDEF_P(VALUE obj)
{
const VALUE mask = ~(RUBY_Qundef ^ RUBY_Qnil);
const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
return (obj & mask) == common_bits;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_FIXNUM_P(VALUE obj)
{
return obj & RUBY_FIXNUM_FLAG;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_STATIC_SYM_P(VALUE obj)
{
const VALUE mask = ~((0x7fffffffffffffffL * 2UL + 1UL) << RUBY_SPECIAL_SHIFT);
return (obj & mask) == RUBY_SYMBOL_FLAG;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_FLONUM_P(VALUE obj)
{
return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_IMMEDIATE_P(VALUE obj)
{
return obj & RUBY_IMMEDIATE_MASK;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline _Bool
RB_SPECIAL_CONST_P(VALUE obj)
{
return RB_IMMEDIATE_P(obj) || obj == RUBY_Qfalse;
}
__attribute__((__const__))
static inline VALUE
rb_special_const_p(VALUE obj)
{
return RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
}
__attribute__((__noreturn__))
__attribute__((__cold__))
void rb_out_of_int(long num);
long rb_num2long(VALUE num);
unsigned long rb_num2ulong(VALUE num);
__attribute__((__const__))
__attribute__((__artificial__))
static inline VALUE
RB_INT2FIX(long i)
{
((void)0);
const unsigned long j = i;
const unsigned long k = (j << 1) + RUBY_FIXNUM_FLAG;
const long l = k;
const long m = l;
const VALUE n = m;
((void)0);
return n;
}
static inline int
rb_long2int_inline(long n)
{
int i = ((int)n);
if (sizeof(long) <= sizeof(int)) {
((__builtin_expect(!!(!!(i == n)), 1)) ? ((void)0) : __builtin_unreachable());
}
if (i != n)
rb_out_of_int(n);
return i;
}
__attribute__((__const__))
static inline long
rbimpl_fix2long_by_idiv(VALUE x)
{
((void)0);
const long y = x - RUBY_FIXNUM_FLAG;
const long z = y / 2;
const long w = ((long)z);
((void)0);
return w;
}
__attribute__((__const__))
static inline long
rbimpl_fix2long_by_shift(VALUE x)
{
((void)0);
const long y = x;
const long z = y >> 1;
const long w = ((long)z);
((void)0);
return w;
}
__attribute__((__const__))
static inline _Bool
rbimpl_right_shift_is_arithmetic_p(void)
{
return (-1 >> 1) == -1;
}
__attribute__((__const__))
static inline long
rb_fix2long(VALUE x)
{
if (rbimpl_right_shift_is_arithmetic_p()) {
return rbimpl_fix2long_by_shift(x);
}
else {
return rbimpl_fix2long_by_idiv(x);
}
}
__attribute__((__const__))
static inline unsigned long
rb_fix2ulong(VALUE x)
{
((void)0);
return rb_fix2long(x);
}
static inline long
rb_num2long_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2long(x);
else
return rb_num2long(x);
}
static inline unsigned long
rb_num2ulong_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2ulong(x);
else
return rb_num2ulong(x);
}
static inline VALUE
rb_long2num_inline(long v)
{
if ((((v) < (0x7fffffffffffffffL / 2) + 1) && ((v) >= ((-0x7fffffffffffffffL - 1L) / 2))))
return RB_INT2FIX(v);
else
return rb_int2big(v);
}
static inline VALUE
rb_ulong2num_inline(unsigned long v)
{
if (((v) < (0x7fffffffffffffffL / 2) + 1))
return RB_INT2FIX(v);
else
return rb_uint2big(v);
}
long rb_num2int(VALUE num);
long rb_fix2int(VALUE num);
unsigned long rb_num2uint(VALUE num);
unsigned long rb_fix2uint(VALUE num);
__attribute__((__artificial__))
static inline int
RB_FIX2INT(VALUE x)
{
long ret;
if (sizeof(int) < sizeof(long)) {
ret = rb_fix2int(x);
}
else {
ret = rb_fix2long(x);
}
return ((int)ret);
}
static inline int
rb_num2int_inline(VALUE x)
{
long ret;
if (sizeof(int) == sizeof(long)) {
ret = rb_num2long_inline(x);
}
else if (RB_FIXNUM_P(x)) {
ret = rb_fix2int(x);
}
else {
ret = rb_num2int(x);
}
return ((int)ret);
}
__attribute__((__artificial__))
static inline unsigned int
RB_NUM2UINT(VALUE x)
{
unsigned long ret;
if (sizeof(int) < sizeof(long)) {
ret = rb_num2uint(x);
}
else {
ret = rb_num2ulong_inline(x);
}
return ((unsigned int)ret);
}
__attribute__((__artificial__))
static inline unsigned int
RB_FIX2UINT(VALUE x)
{
unsigned long ret;
if (sizeof(int) < sizeof(long)) {
ret = rb_fix2uint(x);
}
else {
ret = rb_fix2ulong(x);
}
return ((unsigned int)ret);
}
static inline VALUE
rb_int2num_inline(int v)
{
if ((((v) < (0x7fffffffffffffffL / 2) + 1) && ((v) >= ((-0x7fffffffffffffffL - 1L) / 2))))
return RB_INT2FIX(v);
else
return rb_int2big(v);
}
static inline VALUE
rb_uint2num_inline(unsigned int v)
{
if (((v) < (0x7fffffffffffffffL / 2) + 1))
return RB_INT2FIX(v);
else
return rb_uint2big(v);
}
enum ruby_rvalue_flags {
RVALUE_EMBED_LEN_MAX = 3
};
struct
__attribute__((__aligned__(8)))
RBasic {
VALUE flags;
const VALUE klass;
};
VALUE rb_obj_hide(VALUE obj);
VALUE rb_obj_reveal(VALUE obj, VALUE klass);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RBASIC_CLASS(VALUE obj)
{
((void)0);
return ((struct RBasic *)(obj))->klass;
}
typedef enum {
RB_WARN_CATEGORY_NONE,
RB_WARN_CATEGORY_DEPRECATED,
RB_WARN_CATEGORY_EXPERIMENTAL,
RB_WARN_CATEGORY_ALL_BITS = 0x6
} rb_warning_category_t;
enum rb_io_wait_readwrite {RB_IO_WAIT_READABLE, RB_IO_WAIT_WRITABLE};
VALUE rb_errinfo(void);
void rb_set_errinfo(VALUE err);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_raise(VALUE exc, const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_fatal(const char *fmt, ...);
__attribute__((__cold__))
__attribute__((__noreturn__))
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_bug(const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ ()))
void rb_bug_errno(const char *msg, int err);
__attribute__((__noreturn__))
void rb_sys_fail(const char *msg);
__attribute__((__noreturn__))
void rb_sys_fail_str(VALUE msg);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
void rb_mod_sys_fail(VALUE mod, const char *msg);
__attribute__((__noreturn__))
void rb_mod_sys_fail_str(VALUE mod, VALUE msg);
__attribute__((__noreturn__))
void rb_readwrite_sys_fail(enum rb_io_wait_readwrite waiting, const char *msg);
__attribute__((__noreturn__))
void rb_iter_break(void);
__attribute__((__noreturn__))
void rb_iter_break_value(VALUE val);
__attribute__((__noreturn__))
void rb_exit(int status);
__attribute__((__noreturn__))
void rb_notimplement(void);
VALUE rb_syserr_new(int err, const char * msg);
VALUE rb_syserr_new_str(int n, VALUE arg);
__attribute__((__noreturn__))
void rb_syserr_fail(int err, const char *msg);
__attribute__((__noreturn__))
void rb_syserr_fail_str(int err, VALUE msg);
__attribute__((__noreturn__))
__attribute__((__nonnull__ ()))
void rb_mod_syserr_fail(VALUE mod, int err, const char *msg);
__attribute__((__noreturn__))
void rb_mod_syserr_fail_str(VALUE mod, int err, VALUE msg);
__attribute__((__noreturn__))
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite waiting, int err, const char *msg);
__attribute__((__cold__))
__attribute__((__noreturn__))
void rb_unexpected_type(VALUE self, int t);
VALUE *rb_ruby_verbose_ptr(void);
VALUE *rb_ruby_debug_ptr(void);
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_warning(const char *fmt, ...);
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_category_warning(rb_warning_category_t cat, const char *fmt, ...);
__attribute__((__nonnull__ (1, 3)))
__attribute__((__format__(__printf__, 3, 4)))
void rb_compile_warning(const char *file, int line, const char *fmt, ...);
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_sys_warning(const char *fmt, ...);
__attribute__((__cold__))
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_warn(const char *fmt, ...);
__attribute__((__cold__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);
__attribute__((__nonnull__ (1, 3)))
__attribute__((__format__(__printf__, 3, 4)))
void rb_compile_warn(const char *file, int line, const char *fmt, ...);
__attribute__((__nonnull__ (2, 4)))
__attribute__((__format__(__printf__, 4, 5)))
void rb_category_compile_warn(rb_warning_category_t cat, const char *file, int line, const char *fmt, ...);
enum
ruby_value_type {
RUBY_T_NONE = 0x00,
RUBY_T_OBJECT = 0x01,
RUBY_T_CLASS = 0x02,
RUBY_T_MODULE = 0x03,
RUBY_T_FLOAT = 0x04,
RUBY_T_STRING = 0x05,
RUBY_T_REGEXP = 0x06,
RUBY_T_ARRAY = 0x07,
RUBY_T_HASH = 0x08,
RUBY_T_STRUCT = 0x09,
RUBY_T_BIGNUM = 0x0a,
RUBY_T_FILE = 0x0b,
RUBY_T_DATA = 0x0c,
RUBY_T_MATCH = 0x0d,
RUBY_T_COMPLEX = 0x0e,
RUBY_T_RATIONAL = 0x0f,
RUBY_T_NIL = 0x11,
RUBY_T_TRUE = 0x12,
RUBY_T_FALSE = 0x13,
RUBY_T_SYMBOL = 0x14,
RUBY_T_FIXNUM = 0x15,
RUBY_T_UNDEF = 0x16,
RUBY_T_IMEMO = 0x1a,
RUBY_T_NODE = 0x1b,
RUBY_T_ICLASS = 0x1c,
RUBY_T_ZOMBIE = 0x1d,
RUBY_T_MOVED = 0x1e,
RUBY_T_MASK = 0x1f
};
__attribute__((__cold__))
void rb_check_type(VALUE obj, int t);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline enum ruby_value_type
RB_BUILTIN_TYPE(VALUE obj)
{
((void)0);
VALUE ret = ((struct RBasic *)(obj))->flags & RUBY_T_MASK;
return ((enum ruby_value_type)ret);
}
__attribute__((__pure__))
static inline _Bool
rb_integer_type_p(VALUE obj)
{
if (RB_FIXNUM_P(obj)) {
return 1;
}
else if (RB_SPECIAL_CONST_P(obj)) {
return 0;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_BIGNUM;
}
}
__attribute__((__pure__))
static inline enum ruby_value_type
rb_type(VALUE obj)
{
if (! RB_SPECIAL_CONST_P(obj)) {
return RB_BUILTIN_TYPE(obj);
}
else if (obj == ((VALUE)RUBY_Qfalse)) {
return RUBY_T_FALSE;
}
else if (obj == ((VALUE)RUBY_Qnil)) {
return RUBY_T_NIL;
}
else if (obj == ((VALUE)RUBY_Qtrue)) {
return RUBY_T_TRUE;
}
else if (obj == ((VALUE)RUBY_Qundef)) {
return RUBY_T_UNDEF;
}
else if (RB_FIXNUM_P(obj)) {
return RUBY_T_FIXNUM;
}
else if (RB_STATIC_SYM_P(obj)) {
return RUBY_T_SYMBOL;
}
else {
((__builtin_expect(!!(!!(RB_FLONUM_P(obj))), 1)) ? ((void)0) : __builtin_unreachable());
return RUBY_T_FLOAT;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_FLOAT_TYPE_P(VALUE obj)
{
if (RB_FLONUM_P(obj)) {
return 1;
}
else if (RB_SPECIAL_CONST_P(obj)) {
return 0;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_FLOAT;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_DYNAMIC_SYM_P(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
return 0;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_SYMBOL;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_SYMBOL_P(VALUE obj)
{
return RB_STATIC_SYM_P(obj) || RB_DYNAMIC_SYM_P(obj);
}
__attribute__((__pure__))
__attribute__((__artificial__))
__attribute__((__always_inline__)) inline
static _Bool
rbimpl_RB_TYPE_P_fastpath(VALUE obj, enum ruby_value_type t)
{
if (t == RUBY_T_TRUE) {
return obj == ((VALUE)RUBY_Qtrue);
}
else if (t == RUBY_T_FALSE) {
return obj == ((VALUE)RUBY_Qfalse);
}
else if (t == RUBY_T_NIL) {
return obj == ((VALUE)RUBY_Qnil);
}
else if (t == RUBY_T_UNDEF) {
return obj == ((VALUE)RUBY_Qundef);
}
else if (t == RUBY_T_FIXNUM) {
return RB_FIXNUM_P(obj);
}
else if (t == RUBY_T_SYMBOL) {
return RB_SYMBOL_P(obj);
}
else if (t == RUBY_T_FLOAT) {
return RB_FLOAT_TYPE_P(obj);
}
else if (RB_SPECIAL_CONST_P(obj)) {
return 0;
}
else if (t == RB_BUILTIN_TYPE(obj)) {
return 1;
}
else {
return 0;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_TYPE_P(VALUE obj, enum ruby_value_type t)
{
if (__builtin_constant_p(t)) {
return rbimpl_RB_TYPE_P_fastpath(obj, t);
}
else {
return t == rb_type(obj);
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool rbimpl_rtypeddata_p(VALUE obj);
__attribute__((__artificial__))
static inline void
Check_Type(VALUE v, enum ruby_value_type t)
{
if ((__builtin_expect(!!(! RB_TYPE_P(v, t)), 0))) {
goto unexpected_type;
}
else if (t == RUBY_T_DATA && rbimpl_rtypeddata_p(v)) {
goto unexpected_type;
}
else {
return;
}
unexpected_type:
rb_unexpected_type(v, t);
}
enum ruby_fl_ushift {
RUBY_FL_USHIFT = 12
};
__extension__
enum
ruby_fl_type {
RUBY_FL_WB_PROTECTED = (1<<5),
RUBY_FL_PROMOTED0 = (1<<5),
RUBY_FL_PROMOTED1 = (1<<6),
RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1,
RUBY_FL_FINALIZE = (1<<7),
RUBY_FL_TAINT
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
= (1<<8),
RUBY_FL_SHAREABLE = (1<<8),
RUBY_FL_UNTRUSTED
__attribute__((__deprecated__ ("trustedness turned out to be a wrong idea.")))
= (1<<8),
RUBY_FL_SEEN_OBJ_ID = (1<<9),
RUBY_FL_EXIVAR = (1<<10),
RUBY_FL_FREEZE = (1<<11),
RUBY_FL_USER0 = (1<<(RUBY_FL_USHIFT+0)),
RUBY_FL_USER1 = (1<<(RUBY_FL_USHIFT+1)),
RUBY_FL_USER2 = (1<<(RUBY_FL_USHIFT+2)),
RUBY_FL_USER3 = (1<<(RUBY_FL_USHIFT+3)),
RUBY_FL_USER4 = (1<<(RUBY_FL_USHIFT+4)),
RUBY_FL_USER5 = (1<<(RUBY_FL_USHIFT+5)),
RUBY_FL_USER6 = (1<<(RUBY_FL_USHIFT+6)),
RUBY_FL_USER7 = (1<<(RUBY_FL_USHIFT+7)),
RUBY_FL_USER8 = (1<<(RUBY_FL_USHIFT+8)),
RUBY_FL_USER9 = (1<<(RUBY_FL_USHIFT+9)),
RUBY_FL_USER10 = (1<<(RUBY_FL_USHIFT+10)),
RUBY_FL_USER11 = (1<<(RUBY_FL_USHIFT+11)),
RUBY_FL_USER12 = (1<<(RUBY_FL_USHIFT+12)),
RUBY_FL_USER13 = (1<<(RUBY_FL_USHIFT+13)),
RUBY_FL_USER14 = (1<<(RUBY_FL_USHIFT+14)),
RUBY_FL_USER15 = (1<<(RUBY_FL_USHIFT+15)),
RUBY_FL_USER16 = (1<<(RUBY_FL_USHIFT+16)),
RUBY_FL_USER17 = (1<<(RUBY_FL_USHIFT+17)),
RUBY_FL_USER18 = (1<<(RUBY_FL_USHIFT+18)),
RUBY_FL_USER19 = (1<<(RUBY_FL_USHIFT+19)),
RUBY_ELTS_SHARED = RUBY_FL_USER2,
RUBY_FL_SINGLETON = RUBY_FL_USER0,
};
enum {
RUBY_FL_DUPPED
__attribute__((__deprecated__ ("It seems there is no actual usage of this enum.")))
= (int)RUBY_T_MASK | (int)RUBY_FL_EXIVAR
};
void rb_freeze_singleton_class(VALUE klass);
__attribute__((__pure__))
__attribute__((__artificial__))
__attribute__((__always_inline__)) inline
static _Bool
RB_FL_ABLE(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
return 0;
}
else if (RB_TYPE_P(obj, RUBY_T_NODE)) {
return 0;
}
else {
return 1;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RB_FL_TEST_RAW(VALUE obj, VALUE flags)
{
((void)0);
return ((struct RBasic *)(obj))->flags & flags;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RB_FL_TEST(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
return RB_FL_TEST_RAW(obj, flags);
}
else {
return 0UL;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_FL_ANY_RAW(VALUE obj, VALUE flags)
{
return RB_FL_TEST_RAW(obj, flags);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_FL_ANY(VALUE obj, VALUE flags)
{
return RB_FL_TEST(obj, flags);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_FL_ALL_RAW(VALUE obj, VALUE flags)
{
return RB_FL_TEST_RAW(obj, flags) == flags;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_FL_ALL(VALUE obj, VALUE flags)
{
return RB_FL_TEST(obj, flags) == flags;
}
__attribute__((__artificial__))
static inline void
rbimpl_fl_set_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags |= flags;
}
__attribute__((__artificial__))
static inline void
RB_FL_SET_RAW(VALUE obj, VALUE flags)
{
((void)0);
rbimpl_fl_set_raw_raw(((struct RBasic *)(obj)), flags);
}
__attribute__((__artificial__))
static inline void
RB_FL_SET(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_SET_RAW(obj, flags);
}
}
__attribute__((__artificial__))
static inline void
rbimpl_fl_unset_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags &= ~flags;
}
__attribute__((__artificial__))
static inline void
RB_FL_UNSET_RAW(VALUE obj, VALUE flags)
{
((void)0);
rbimpl_fl_unset_raw_raw(((struct RBasic *)(obj)), flags);
}
__attribute__((__artificial__))
static inline void
RB_FL_UNSET(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_UNSET_RAW(obj, flags);
}
}
__attribute__((__artificial__))
static inline void
rbimpl_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags ^= flags;
}
__attribute__((__artificial__))
static inline void
RB_FL_REVERSE_RAW(VALUE obj, VALUE flags)
{
((void)0);
rbimpl_fl_reverse_raw_raw(((struct RBasic *)(obj)), flags);
}
__attribute__((__artificial__))
static inline void
RB_FL_REVERSE(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_REVERSE_RAW(obj, flags);
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline _Bool
RB_OBJ_TAINTABLE(VALUE obj)
{
return 0;
}
__attribute__((__pure__))
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline VALUE
RB_OBJ_TAINTED_RAW(VALUE obj)
{
return 0;
}
__attribute__((__pure__))
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline _Bool
RB_OBJ_TAINTED(VALUE obj)
{
return 0;
}
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline void
RB_OBJ_TAINT_RAW(VALUE obj)
{
return;
}
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline void
RB_OBJ_TAINT(VALUE obj)
{
return;
}
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline void
RB_OBJ_INFECT_RAW(VALUE dst, VALUE src)
{
return;
}
__attribute__((__artificial__))
__attribute__((__deprecated__ ("taintedness turned out to be a wrong idea.")))
static inline void
RB_OBJ_INFECT(VALUE dst, VALUE src)
{
return;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RB_OBJ_FROZEN_RAW(VALUE obj)
{
return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_OBJ_FROZEN(VALUE obj)
{
if (! RB_FL_ABLE(obj)) {
return 1;
}
else {
return RB_OBJ_FROZEN_RAW(obj);
}
}
__attribute__((__artificial__))
static inline void
RB_OBJ_FREEZE_RAW(VALUE obj)
{
RB_FL_SET_RAW(obj, RUBY_FL_FREEZE);
}
void rb_obj_freeze_inline(VALUE obj);
enum ruby_rstring_flags {
RSTRING_NOEMBED = RUBY_FL_USER1,
RSTRING_FSTR = RUBY_FL_USER17
};
struct RString {
struct RBasic basic;
union {
struct {
long len;
char *ptr;
union {
long capa;
VALUE shared;
} aux;
} heap;
struct {
long len;
char ary[1];
} embed;
} as;
};
VALUE rb_str_to_str(VALUE obj);
VALUE rb_string_value(volatile VALUE *ptr);
char *rb_string_value_ptr(volatile VALUE *ptr);
char *rb_string_value_cstr(volatile VALUE *ptr);
VALUE rb_str_export(VALUE obj);
VALUE rb_str_export_locale(VALUE obj);
__attribute__((__error__ ("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead")))
void rb_check_safe_str(VALUE);
void rb_debug_rstring_null_ptr(const char *func);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline long
RSTRING_EMBED_LEN(VALUE str)
{
((void)0);
((void)0);
long f = ((struct RString *)(str))->as.embed.len;
return f;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline struct RString
rbimpl_rstring_getmem(VALUE str)
{
((void)0);
if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
return *((struct RString *)(str));
}
else {
struct RString retval;
retval.as.heap.len = RSTRING_EMBED_LEN(str);
retval.as.heap.ptr = ((struct RString *)(str))->as.embed.ary;
return retval;
}
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline long
RSTRING_LEN(VALUE str)
{
return rbimpl_rstring_getmem(str).as.heap.len;
}
__attribute__((__artificial__))
static inline char *
RSTRING_PTR(VALUE str)
{
char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
if ((__builtin_expect(!!(! ptr), 0))) {
rb_debug_rstring_null_ptr("RSTRING_PTR");
}
return ptr;
}
__attribute__((__artificial__))
static inline char *
RSTRING_END(VALUE str)
{
struct RString buf = rbimpl_rstring_getmem(str);
if ((__builtin_expect(!!(! buf.as.heap.ptr), 0))) {
rb_debug_rstring_null_ptr("RSTRING_END");
}
return &buf.as.heap.ptr[buf.as.heap.len];
}
__attribute__((__artificial__))
static inline int
RSTRING_LENINT(VALUE str)
{
return rb_long2int_inline(RSTRING_LEN(str));
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline VALUE
RB_CHR2FIX(unsigned char c)
{
return RB_INT2FIX(c);
}
static inline char
rb_num2char_inline(VALUE x)
{
if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
return RSTRING_PTR(x)[0];
else
return ((char)rb_num2int_inline(x));
}
double rb_num2dbl(VALUE num);
__attribute__((__pure__))
double rb_float_value(VALUE num);
VALUE rb_float_new(double d);
VALUE rb_float_new_in_heap(double d);
VALUE rb_ll2inum(long long num);
VALUE rb_ull2inum(unsigned long long num);
long long rb_num2ll(VALUE num);
unsigned long long rb_num2ull(VALUE num);
static inline VALUE
rb_ll2num_inline(long long n)
{
if ((((n) < (0x7fffffffffffffffL / 2) + 1) && ((n) >= ((-0x7fffffffffffffffL - 1L) / 2)))) return RB_INT2FIX((long)n);
return rb_ll2inum(n);
}
static inline VALUE
rb_ull2num_inline(unsigned long long n)
{
if (((n) < (0x7fffffffffffffffL / 2) + 1)) return RB_INT2FIX((long)n);
return rb_ull2inum(n);
}
static inline long long
rb_num2ll_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2long(x);
else
return rb_num2ll(x);
}
static inline unsigned long long
rb_num2ull_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2long(x);
else
return rb_num2ull(x);
}
short rb_num2short(VALUE num);
unsigned short rb_num2ushort(VALUE num);
short rb_fix2short(VALUE num);
unsigned short rb_fix2ushort(VALUE num);
static inline short
rb_num2short_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2short(x);
else
return rb_num2short(x);
}
typedef unsigned long st_data_t;
typedef struct st_table st_table;
typedef st_data_t st_index_t;
typedef int st_compare_func(st_data_t, st_data_t);
typedef st_index_t st_hash_func(st_data_t);
typedef char st_check_for_sizeof_st_index_t[8 == (int)sizeof(st_index_t) ? 1 : -1];
struct st_hash_type {
int (*compare)(st_data_t, st_data_t);
st_index_t (*hash)(st_data_t);
};
typedef struct st_table_entry st_table_entry;
struct st_table_entry;
struct st_table {
unsigned char entry_power, bin_power, size_ind;
unsigned int rebuilds_num;
const struct st_hash_type *type;
st_index_t num_entries;
st_index_t *bins;
st_index_t entries_start, entries_bound;
st_table_entry *entries;
};
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
size_t rb_st_table_size(const struct st_table *tbl);
st_table *rb_st_init_table(const struct st_hash_type *);
st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
st_table *rb_st_init_numtable(void);
st_table *rb_st_init_numtable_with_size(st_index_t);
st_table *rb_st_init_strtable(void);
st_table *rb_st_init_strtable_with_size(st_index_t);
st_table *rb_st_init_strcasetable(void);
st_table *rb_st_init_strcasetable_with_size(st_index_t);
int rb_st_delete(st_table *, st_data_t *, st_data_t *);
int rb_st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
int rb_st_shift(st_table *, st_data_t *, st_data_t *);
int rb_st_insert(st_table *, st_data_t, st_data_t);
int rb_st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
int rb_st_lookup(st_table *, st_data_t, st_data_t *);
int rb_st_get_key(st_table *, st_data_t, st_data_t *);
typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
int rb_st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
typedef int st_foreach_callback_func(st_data_t, st_data_t, st_data_t);
typedef int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int);
int rb_st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
int rb_st_foreach(st_table *, st_foreach_callback_func *, st_data_t);
int rb_st_foreach_check(st_table *, st_foreach_check_callback_func *, st_data_t, st_data_t);
st_index_t rb_st_keys(st_table *table, st_data_t *keys, st_index_t size);
st_index_t rb_st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
st_index_t rb_st_values(st_table *table, st_data_t *values, st_index_t size);
st_index_t rb_st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
void rb_st_add_direct(st_table *, st_data_t, st_data_t);
void rb_st_free_table(st_table *);
void rb_st_cleanup_safe(st_table *, st_data_t);
void rb_st_clear(st_table *);
st_table *rb_st_copy(st_table *);
__attribute__((__const__)) int rb_st_numcmp(st_data_t, st_data_t);
__attribute__((__const__)) st_index_t rb_st_numhash(st_data_t);
__attribute__((__pure__)) int rb_st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
__attribute__((__pure__)) int rb_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
__attribute__((__pure__)) size_t rb_st_memsize(const st_table *);
__attribute__((__pure__)) st_index_t rb_st_hash(const void *ptr, size_t len, st_index_t h);
__attribute__((__const__)) st_index_t rb_st_hash_uint32(st_index_t h, uint32_t i);
__attribute__((__const__)) st_index_t rb_st_hash_uint(st_index_t h, st_index_t i);
__attribute__((__const__)) st_index_t rb_st_hash_end(st_index_t h);
__attribute__((__const__)) st_index_t rb_st_hash_start(st_index_t h);
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE);
__attribute__((__const__))
__attribute__((__artificial__))
static inline VALUE
RB_ST2FIX(st_data_t i)
{
long x = i;
if (x >= 0) {
x &= (0x7fffffffffffffffL / 2);
}
else {
x |= ((-0x7fffffffffffffffL - 1L) / 2);
}
((void)0);
unsigned long y = ((unsigned long)x);
return RB_INT2FIX(y);
}
void rb_gc_writebarrier(VALUE old, VALUE young);
void rb_gc_writebarrier_unprotect(VALUE obj);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_OBJ_PROMOTED_RAW(VALUE obj)
{
((void)0);
return RB_FL_ANY_RAW(obj, RUBY_FL_PROMOTED);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RB_OBJ_PROMOTED(VALUE obj)
{
if (! RB_FL_ABLE(obj)) {
return 0;
}
else {
return RB_OBJ_PROMOTED_RAW(obj);
}
}
static inline VALUE
rb_obj_wb_unprotect(
VALUE x,
__attribute__((__unused__))
const char *filename,
__attribute__((__unused__))
int line)
{
rb_gc_writebarrier_unprotect(x);
return x;
}
static inline VALUE
rb_obj_written(
VALUE a,
__attribute__((__unused__))
VALUE oldv,
VALUE b,
__attribute__((__unused__))
const char *filename,
__attribute__((__unused__))
int line)
{
if (!RB_SPECIAL_CONST_P(b)) {
rb_gc_writebarrier(a, b);
}
return a;
}
static inline VALUE
rb_obj_write(
VALUE a, VALUE *slot, VALUE b,
__attribute__((__unused__))
const char *filename,
__attribute__((__unused__))
int line)
{
*slot = b;
rb_obj_written(a, ((VALUE)RUBY_Qundef) , b, filename, line);
return a;
}
enum ruby_rarray_flags {
RARRAY_EMBED_FLAG = RUBY_FL_USER1,
RARRAY_EMBED_LEN_MASK = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3
,
RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
};
enum ruby_rarray_consts {
RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3
};
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
const
VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[1];
} as;
};
VALUE *rb_ary_ptr_use_start(VALUE ary);
void rb_ary_ptr_use_end(VALUE a);
void rb_ary_detransient(VALUE a);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline long
RARRAY_EMBED_LEN(VALUE ary)
{
((void)0);
((void)0);
VALUE f = ((struct RBasic *)(ary))->flags;
f &= RARRAY_EMBED_LEN_MASK;
f >>= RARRAY_EMBED_LEN_SHIFT;
return ((long)f);
}
__attribute__((__pure__))
static inline long
rb_array_len(VALUE a)
{
((void)0);
if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
return RARRAY_EMBED_LEN(a);
}
else {
return ((struct RArray *)(a))->as.heap.len;
}
}
__attribute__((__artificial__))
static inline int
RARRAY_LENINT(VALUE ary)
{
return rb_long2int_inline(rb_array_len(ary));
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RARRAY_TRANSIENT_P(VALUE ary)
{
((void)0);
return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
}
__attribute__((__pure__))
static inline const VALUE *
rb_array_const_ptr_transient(VALUE a)
{
((void)0);
if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
return (((struct RArray *)(a))->as.ary);
}
else {
return (((struct RArray *)(a))->as.heap.ptr);
}
}
static inline const VALUE *
rb_array_const_ptr(VALUE a)
{
((void)0);
if (RARRAY_TRANSIENT_P(a)) {
rb_ary_detransient(a);
}
return rb_array_const_ptr_transient(a);
}
static inline VALUE *
rb_array_ptr_use_start(VALUE a,
__attribute__((__unused__))
int allow_transient)
{
((void)0);
if (!allow_transient) {
if (RARRAY_TRANSIENT_P(a)) {
rb_ary_detransient(a);
}
}
return rb_ary_ptr_use_start(a);
}
static inline void
rb_array_ptr_use_end(VALUE a,
__attribute__((__unused__))
int allow_transient)
{
((void)0);
rb_ary_ptr_use_end(a);
}
static inline VALUE *
RARRAY_PTR(VALUE ary)
{
((void)0);
VALUE tmp = (1 ? rb_obj_wb_unprotect(ary, "./include/ruby/internal/core/rarray.h", 550) : ary);
return ((VALUE *)rb_array_const_ptr(tmp));
}
static inline void
RARRAY_ASET(VALUE ary, long i, VALUE v)
{
do { ((void)0); const VALUE rbimpl_ary = (ary); VALUE *ptr = rb_array_ptr_use_start(rbimpl_ary, (1)); (rb_obj_write((VALUE)(ary), (VALUE *)(&ptr[i]), (VALUE)(v), "./include/ruby/internal/core/rarray.h", 569)); rb_array_ptr_use_end(rbimpl_ary, (1)); } while (0);
}
int rb_big_sign(VALUE num);
static inline _Bool
RBIGNUM_POSITIVE_P(VALUE b)
{
((void)0);
return rb_big_sign(b);
}
static inline _Bool
RBIGNUM_NEGATIVE_P(VALUE b)
{
((void)0);
return ! RBIGNUM_POSITIVE_P(b);
}
enum ruby_rmodule_flags {
RMODULE_IS_REFINEMENT = RUBY_FL_USER3
};
struct RClass;
VALUE rb_class_get_superclass(VALUE klass);
typedef void (*RUBY_DATA_FUNC)(void*);
struct RData {
struct RBasic basic;
RUBY_DATA_FUNC dmark;
RUBY_DATA_FUNC dfree;
void *data;
};
VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
VALUE rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
extern VALUE rb_cObject;
__attribute__((__warning__ ("untyped Data is unsafe; use TypedData instead"))) __attribute__((__deprecated__ ("by TypedData")))
static inline VALUE
rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
{
return rb_data_object_wrap(klass, ptr, mark, free);
}
static inline void *
rb_data_object_get(VALUE obj)
{
Check_Type(obj, RUBY_T_DATA);
return ((struct RData *)(obj))->data;
}
__attribute__((__warning__ ("untyped Data is unsafe; use TypedData instead"))) __attribute__((__deprecated__ ("by TypedData")))
static inline void *
rb_data_object_get_warning(VALUE obj)
{
return rb_data_object_get(obj);
}
static inline VALUE
rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
{
VALUE result = rb_data_object_zalloc( (klass), (size), ((void (*)(void *))(mark_func)), ((void (*)(void *))(free_func))); (*datap) = ((void *)((struct RData *)(result))->data); ((void)(*datap));
return result;
}
__attribute__((__deprecated__ ("by: rb_data_object_wrap")))
static inline VALUE
rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
return rb_data_object_wrap(klass, data, dmark, dfree);
}
struct rb_io_t;
struct RFile {
struct RBasic basic;
struct rb_io_t *fptr;
};
struct st_table;
size_t rb_hash_size_num(VALUE hash);
struct st_table *rb_hash_tbl(VALUE hash, const char *file, int line);
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
enum ruby_robject_flags {
ROBJECT_EMBED = RUBY_FL_USER1
};
struct st_table;
struct RObject {
struct RBasic basic;
union {
struct {
VALUE *ivptr;
struct rb_id_table *iv_index_tbl;
} heap;
VALUE ary[1];
} as;
};
static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = __builtin_offsetof (struct RObject, as.heap.ivptr);
static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = __builtin_offsetof (struct RObject, as.heap.iv_index_tbl);
static const int32_t ROBJECT_OFFSET_AS_ARY = __builtin_offsetof (struct RObject, as.ary);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE *
ROBJECT_IVPTR(VALUE obj)
{
((void)0);
struct RObject *const ptr = ((struct RObject *)(obj));
if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
return ptr->as.ary;
}
else {
return ptr->as.heap.ivptr;
}
}
struct re_patter_buffer;
struct RRegexp {
struct RBasic basic;
struct re_pattern_buffer *ptr;
const VALUE src;
unsigned long usecnt;
};
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RREGEXP_SRC(VALUE rexp)
{
((void)0);
VALUE ret = ((struct RRegexp *)(rexp))->src;
((void)0);
return ret;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline char *
RREGEXP_SRC_PTR(VALUE rexp)
{
return RSTRING_PTR(RREGEXP_SRC(rexp));
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline long
RREGEXP_SRC_LEN(VALUE rexp)
{
return RSTRING_LEN(RREGEXP_SRC(rexp));
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline char *
RREGEXP_SRC_END(VALUE rexp)
{
return RSTRING_END(RREGEXP_SRC(rexp));
}
VALUE rb_struct_size(VALUE st);
VALUE rb_struct_aref(VALUE st, VALUE k);
VALUE rb_struct_aset(VALUE st, VALUE k, VALUE v);
__attribute__((__artificial__))
static inline long
RSTRUCT_LEN(VALUE st)
{
((void)0);
return rb_num2long_inline(rb_struct_size(st));
}
__attribute__((__artificial__))
static inline VALUE
RSTRUCT_SET(VALUE st, int k, VALUE v)
{
((void)0);
return rb_struct_aset(st, rb_int2num_inline(k), (v));
}
__attribute__((__artificial__))
static inline VALUE
RSTRUCT_GET(VALUE st, int k)
{
((void)0);
return rb_struct_aref(st, rb_int2num_inline(k));
}
enum
rbimpl_typeddata_flags {
RUBY_TYPED_FREE_IMMEDIATELY = 1,
RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,
RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED,
RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1
};
typedef struct rb_data_type_struct rb_data_type_t;
struct rb_data_type_struct {
const char *wrap_struct_name;
struct {
RUBY_DATA_FUNC dmark;
RUBY_DATA_FUNC dfree;
size_t (*dsize)(const void *);
RUBY_DATA_FUNC dcompact;
void *reserved[1];
} function;
const rb_data_type_t *parent;
void *data;
VALUE flags;
};
struct RTypedData {
struct RBasic basic;
const rb_data_type_t *type;
VALUE typed_flag;
void *data;
};
__attribute__((__nonnull__ (3)))
VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type);
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
rbimpl_rtypeddata_p(VALUE obj)
{
return ((struct RTypedData *)(obj))->typed_flag == 1;
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline _Bool
RTYPEDDATA_P(VALUE obj)
{
return rbimpl_rtypeddata_p(obj);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline const struct rb_data_type_struct *
RTYPEDDATA_TYPE(VALUE obj)
{
return ((struct RTypedData *)(obj))->type;
}
static inline VALUE
rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
{
VALUE result = rb_data_typed_object_zalloc(klass, size, type); (*datap) = ((void *)(((struct RTypedData *)(result))->data)); ((void)(*datap));
return result;
}
__attribute__((__deprecated__ ("by: rb_data_typed_object_wrap")))
static inline VALUE
rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
{
return rb_data_typed_object_wrap(klass, datap, type);
}
enum
{
_ISupper = ((0) < 8 ? ((1 << (0)) << 8) : ((1 << (0)) >> 8)),
_ISlower = ((1) < 8 ? ((1 << (1)) << 8) : ((1 << (1)) >> 8)),
_ISalpha = ((2) < 8 ? ((1 << (2)) << 8) : ((1 << (2)) >> 8)),
_ISdigit = ((3) < 8 ? ((1 << (3)) << 8) : ((1 << (3)) >> 8)),
_ISxdigit = ((4) < 8 ? ((1 << (4)) << 8) : ((1 << (4)) >> 8)),
_ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)),
_ISprint = ((6) < 8 ? ((1 << (6)) << 8) : ((1 << (6)) >> 8)),
_ISgraph = ((7) < 8 ? ((1 << (7)) << 8) : ((1 << (7)) >> 8)),
_ISblank = ((8) < 8 ? ((1 << (8)) << 8) : ((1 << (8)) >> 8)),
_IScntrl = ((9) < 8 ? ((1 << (9)) << 8) : ((1 << (9)) >> 8)),
_ISpunct = ((10) < 8 ? ((1 << (10)) << 8) : ((1 << (10)) >> 8)),
_ISalnum = ((11) < 8 ? ((1 << (11)) << 8) : ((1 << (11)) >> 8))
};
extern const unsigned short int **__ctype_b_loc (void)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern const __int32_t **__ctype_tolower_loc (void)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern const __int32_t **__ctype_toupper_loc (void)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int isalnum (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isalpha (int) __attribute__ ((__nothrow__ , __leaf__));
extern int iscntrl (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isdigit (int) __attribute__ ((__nothrow__ , __leaf__));
extern int islower (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isgraph (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isprint (int) __attribute__ ((__nothrow__ , __leaf__));
extern int ispunct (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isspace (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isupper (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isxdigit (int) __attribute__ ((__nothrow__ , __leaf__));
extern int tolower (int __c) __attribute__ ((__nothrow__ , __leaf__));
extern int toupper (int __c) __attribute__ ((__nothrow__ , __leaf__));
extern int isblank (int) __attribute__ ((__nothrow__ , __leaf__));
extern int isctype (int __c, int __mask) __attribute__ ((__nothrow__ , __leaf__));
extern int isascii (int __c) __attribute__ ((__nothrow__ , __leaf__));
extern int toascii (int __c) __attribute__ ((__nothrow__ , __leaf__));
extern int _toupper (int) __attribute__ ((__nothrow__ , __leaf__));
extern int _tolower (int) __attribute__ ((__nothrow__ , __leaf__));
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) tolower (int __c)
{
return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc ())[__c] : __c;
}
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) toupper (int __c)
{
return __c >= -128 && __c < 256 ? (*__ctype_toupper_loc ())[__c] : __c;
}
extern int isalnum_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isalpha_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int iscntrl_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isdigit_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int islower_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isgraph_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isprint_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int ispunct_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isspace_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isupper_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isxdigit_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int isblank_l (int, locale_t) __attribute__ ((__nothrow__ , __leaf__));
extern int __tolower_l (int __c, locale_t __l) __attribute__ ((__nothrow__ , __leaf__));
extern int tolower_l (int __c, locale_t __l) __attribute__ ((__nothrow__ , __leaf__));
extern int __toupper_l (int __c, locale_t __l) __attribute__ ((__nothrow__ , __leaf__));
extern int toupper_l (int __c, locale_t __l) __attribute__ ((__nothrow__ , __leaf__));
__attribute__((__nonnull__ ()))
int rb_st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
__attribute__((__nonnull__ ()))
int rb_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
__attribute__((__nonnull__ (1)))
unsigned long ruby_strtoul(const char *str, char **endptr, int base);
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isascii(int c)
{
return '\0' <= c && c <= '\x7f';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isupper(int c)
{
return 'A' <= c && c <= 'Z';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_islower(int c)
{
return 'a' <= c && c <= 'z';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isalpha(int c)
{
return rb_isupper(c) || rb_islower(c);
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isdigit(int c)
{
return '0' <= c && c <= '9';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isalnum(int c)
{
return rb_isalpha(c) || rb_isdigit(c);
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isxdigit(int c)
{
return rb_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isblank(int c)
{
return c == ' ' || c == '\t';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isspace(int c)
{
return c == ' ' || ('\t' <= c && c <= '\r');
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_iscntrl(int c)
{
return ('\0' <= c && c < ' ') || c == '\x7f';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isprint(int c)
{
return ' ' <= c && c <= '\x7e';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_ispunct(int c)
{
return !rb_isalnum(c);
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_isgraph(int c)
{
return '!' <= c && c <= '\x7e';
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_tolower(int c)
{
return rb_isupper(c) ? (c|0x20) : c;
}
__attribute__((__const__))
__attribute__((__artificial__))
static inline int
rb_toupper(int c)
{
return rb_islower(c) ? (c&0x5f) : c;
}
__attribute__((__nonnull__ ()))
VALUE rb_eval_string(const char *str);
__attribute__((__nonnull__ (1)))
VALUE rb_eval_string_protect(const char *str, int *state);
__attribute__((__nonnull__ (1)))
VALUE rb_eval_string_wrap(const char *str, int *state);
VALUE rb_funcall(VALUE recv, ID mid, int n, ...);
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv);
VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv);
VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv);
VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval);
VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval, int kw_splat);
VALUE rb_call_super(int argc, const VALUE *argv);
VALUE rb_call_super_kw(int argc, const VALUE *argv, int kw_splat);
VALUE rb_current_receiver(void);
__attribute__((__nonnull__ (2)))
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values);
__attribute__((__nonnull__ ()))
VALUE rb_extract_keywords(VALUE *orighash);
typedef uint32_t rb_event_flag_t;
typedef void (*rb_event_hook_func_t)(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass);
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
int rb_remove_event_hook(rb_event_hook_func_t func);
void rb_gc_register_address(VALUE *valptr);
void rb_global_variable(VALUE *);
void rb_gc_unregister_address(VALUE *valptr);
void rb_gc_register_mark_object(VALUE object);
typedef int ruby_glob_func(const char *path, VALUE arg, void *enc);
__attribute__((__nonnull__ ()))
void rb_glob(const char *pattern, void (*func)(const char *path, VALUE arg, void *enc), VALUE arg);
__attribute__((__nonnull__ ()))
int ruby_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);
__attribute__((__nonnull__ ()))
int ruby_brace_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);
extern VALUE rb_mKernel;
extern VALUE rb_mComparable;
extern VALUE rb_mEnumerable;
extern VALUE rb_mErrno;
extern VALUE rb_mFileTest;
extern VALUE rb_mGC;
extern VALUE rb_mMath;
extern VALUE rb_mProcess;
extern VALUE rb_mWaitReadable;
extern VALUE rb_mWaitWritable;
extern VALUE rb_cBasicObject;
extern VALUE rb_cObject;
extern VALUE rb_cArray;
extern VALUE rb_cBinding;
extern VALUE rb_cClass;
extern VALUE rb_cDir;
extern VALUE rb_cEncoding;
extern VALUE rb_cEnumerator;
extern VALUE rb_cFalseClass;
extern VALUE rb_cFile;
extern VALUE rb_cComplex;
extern VALUE rb_cFloat;
extern VALUE rb_cHash;
extern VALUE rb_cIO;
extern VALUE rb_cInteger;
extern VALUE rb_cMatch;
extern VALUE rb_cMethod;
extern VALUE rb_cModule;
extern VALUE rb_cRefinement;
extern VALUE rb_cNameErrorMesg;
extern VALUE rb_cNilClass;
extern VALUE rb_cNumeric;
extern VALUE rb_cProc;
extern VALUE rb_cRandom;
extern VALUE rb_cRange;
extern VALUE rb_cRational;
extern VALUE rb_cRegexp;
extern VALUE rb_cStat;
extern VALUE rb_cString;
extern VALUE rb_cStruct;
extern VALUE rb_cSymbol;
extern VALUE rb_cThread;
extern VALUE rb_cTime;
extern VALUE rb_cTrueClass;
extern VALUE rb_cUnboundMethod;
extern VALUE rb_eException;
extern VALUE rb_eStandardError;
extern VALUE rb_eSystemExit;
extern VALUE rb_eInterrupt;
extern VALUE rb_eSignal;
extern VALUE rb_eFatal;
extern VALUE rb_eArgError;
extern VALUE rb_eEOFError;
extern VALUE rb_eIndexError;
extern VALUE rb_eStopIteration;
extern VALUE rb_eKeyError;
extern VALUE rb_eRangeError;
extern VALUE rb_eIOError;
extern VALUE rb_eRuntimeError;
extern VALUE rb_eFrozenError;
extern VALUE rb_eSecurityError;
extern VALUE rb_eSystemCallError;
extern VALUE rb_eThreadError;
extern VALUE rb_eTypeError;
extern VALUE rb_eZeroDivError;
extern VALUE rb_eNotImpError;
extern VALUE rb_eNoMemError;
extern VALUE rb_eNoMethodError;
extern VALUE rb_eFloatDomainError;
extern VALUE rb_eLocalJumpError;
extern VALUE rb_eSysStackError;
extern VALUE rb_eRegexpError;
extern VALUE rb_eEncodingError;
extern VALUE rb_eEncCompatError;
extern VALUE rb_eNoMatchingPatternError;
extern VALUE rb_eNoMatchingPatternKeyError;
extern VALUE rb_eScriptError;
extern VALUE rb_eNameError;
extern VALUE rb_eSyntaxError;
extern VALUE rb_eLoadError;
extern VALUE rb_eMathDomainError;
extern VALUE rb_stdin;
extern VALUE rb_stdout;
extern VALUE rb_stderr;
__attribute__((__pure__))
static inline VALUE
rb_class_of(VALUE obj)
{
if (! RB_SPECIAL_CONST_P(obj)) {
return RBASIC_CLASS(obj);
}
else if (obj == ((VALUE)RUBY_Qfalse)) {
return rb_cFalseClass;
}
else if (obj == ((VALUE)RUBY_Qnil)) {
return rb_cNilClass;
}
else if (obj == ((VALUE)RUBY_Qtrue)) {
return rb_cTrueClass;
}
else if (RB_FIXNUM_P(obj)) {
return rb_cInteger;
}
else if (RB_STATIC_SYM_P(obj)) {
return rb_cSymbol;
}
else if (RB_FLONUM_P(obj)) {
return rb_cFloat;
}
__builtin_unreachable();
}
__attribute__((__nonnull__ ()))
void ruby_sysinit(int *argc, char ***argv);
void ruby_init(void);
void* ruby_options(int argc, char** argv);
int ruby_executable_node(void *n, int *status);
int ruby_run_node(void *n);
void ruby_show_version(void);
void ruby_show_copyright(void);
void ruby_init_stack(volatile VALUE *addr);
int ruby_setup(void);
int ruby_cleanup(int ex);
void ruby_finalize(void);
__attribute__((__noreturn__))
void ruby_stop(int);
int ruby_stack_check(void);
size_t ruby_stack_length(VALUE **topnotch);
int ruby_exec_node(void *n);
void ruby_script(const char* name);
void ruby_set_script_name(VALUE name);
void ruby_prog_init(void);
void ruby_set_argv(int argc, char **argv);
void *ruby_process_options(int argc, char **argv);
void ruby_init_loadpath(void);
void ruby_incpush(const char *path);
void ruby_sig_finalize(void);
typedef VALUE rb_block_call_func(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg);
typedef rb_block_call_func *rb_block_call_func_t;
VALUE rb_each(VALUE obj);
VALUE rb_yield(VALUE val);
VALUE rb_yield_values(int n, ...);
VALUE rb_yield_values2(int n, const VALUE *argv);
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat);
VALUE rb_yield_splat(VALUE ary);
VALUE rb_yield_splat_kw(VALUE ary, int kw_splat);
VALUE rb_yield_block(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg);
int rb_keyword_given_p(void);
int rb_block_given_p(void);
void rb_need_block(void);
__attribute__((__deprecated__ ("by: rb_block_call since 1.9")))
VALUE rb_iterate(VALUE (*func1)(VALUE), VALUE data1, rb_block_call_func_t proc, VALUE data2);
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2);
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat);
VALUE rb_rescue(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2);
VALUE rb_rescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, ...);
VALUE rb_vrescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, va_list ap);
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
VALUE rb_catch(const char *tag, rb_block_call_func_t func, VALUE data);
VALUE rb_catch_obj(VALUE tag, rb_block_call_func_t func, VALUE data);
__attribute__((__noreturn__))
void rb_throw(const char *tag, VALUE val);
__attribute__((__noreturn__))
void rb_throw_obj(VALUE tag, VALUE val);
struct rbimpl_size_mul_overflow_tag {
_Bool left;
size_t right;
};
__attribute__((__malloc__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (2)))
__attribute__((__nonnull__ ()))
void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);
__attribute__((__malloc__))
__attribute__((__returns_nonnull__))
__attribute__((__alloc_size__ (2,3)))
__attribute__((__nonnull__ ()))
void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count);
void rb_free_tmp_buffer(volatile VALUE *store);
__attribute__((__noreturn__))
void ruby_malloc_size_overflow(size_t x, size_t y);
static inline int
rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c)
{
__extension__ unsigned __int128 da, db, c2;
da = a;
db = b;
c2 = da * db;
if (c2 > max) return 1;
*c = ((size_t)c2);
return 0;
}
__attribute__((__const__))
static inline struct rbimpl_size_mul_overflow_tag
rbimpl_size_mul_overflow(size_t x, size_t y)
{
struct rbimpl_size_mul_overflow_tag ret = { 0, 0, };
ret.left = __builtin_mul_overflow(x, y, &ret.right);
return ret;
}
static inline size_t
rbimpl_size_mul_or_raise(size_t x, size_t y)
{
struct rbimpl_size_mul_overflow_tag size =
rbimpl_size_mul_overflow(x, y);
if ((__builtin_expect(!!(! size.left), 1))) {
return size.right;
}
else {
ruby_malloc_size_overflow(x, y);
__builtin_unreachable();
}
}
static inline void *
rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
{
const size_t total_size = rbimpl_size_mul_or_raise(count, elsize);
const size_t cnt = (total_size + sizeof(VALUE) - 1) / sizeof(VALUE);
return rb_alloc_tmp_buffer_with_count(store, total_size, cnt);
}
__attribute__((__nonnull__ (1)))
__attribute__((__returns_nonnull__))
static inline void *
ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
{
if (n) {
return memcpy(dest, src, n);
}
else {
return dest;
}
}
__attribute__((__nonnull__ ()))
VALUE rb_define_class(const char *name, VALUE super);
__attribute__((__nonnull__ ()))
VALUE rb_define_module(const char *name);
__attribute__((__nonnull__ ()))
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super);
__attribute__((__nonnull__ ()))
VALUE rb_define_module_under(VALUE outer, const char *name);
void rb_include_module(VALUE klass, VALUE module);
void rb_extend_object(VALUE obj, VALUE mod);
void rb_prepend_module(VALUE klass, VALUE module);
VALUE rb_newobj(void);
VALUE rb_newobj_of(VALUE klass, VALUE flags);
VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
VALUE rb_obj_class(VALUE obj);
VALUE rb_singleton_class_clone(VALUE obj);
void rb_singleton_class_attached(VALUE klass, VALUE obj);
void rb_copy_generic_ivar(VALUE clone, VALUE obj);
__attribute__((__deprecated__ ("This is no longer how Object#clone works.")))
static inline void
rb_clone_setup(VALUE clone, VALUE obj)
{
return;
}
__attribute__((__deprecated__ ("This is no longer how Object#dup works.")))
static inline void
rb_dup_setup(VALUE dup, VALUE obj)
{
return;
}
__attribute__((__nonnull__ ()))
void rb_mem_clear(VALUE *buf, long len)
;
VALUE rb_assoc_new(VALUE car, VALUE cdr);
VALUE rb_check_array_type(VALUE obj);
VALUE rb_ary_new(void);
VALUE rb_ary_new_capa(long capa);
VALUE rb_ary_new_from_args(long n, ...);
VALUE rb_ary_new_from_values(long n, const VALUE *elts);
VALUE rb_ary_hidden_new(long capa);
void rb_ary_free(VALUE ary);
void rb_ary_modify(VALUE ary);
VALUE rb_ary_freeze(VALUE obj);
__attribute__((__pure__))
VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs);
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary);
VALUE rb_ary_subseq(VALUE ary, long beg, long len);
void rb_ary_store(VALUE ary, long key, VALUE val);
VALUE rb_ary_dup(VALUE ary);
VALUE rb_ary_resurrect(VALUE ary);
VALUE rb_ary_to_ary(VALUE obj);
VALUE rb_ary_to_s(VALUE ary);
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len);
VALUE rb_ary_push(VALUE ary, VALUE elem);
VALUE rb_ary_pop(VALUE ary);
VALUE rb_ary_shift(VALUE ary);
VALUE rb_ary_unshift(VALUE ary, VALUE elem);
__attribute__((__pure__))
VALUE rb_ary_entry(VALUE ary, long off);
VALUE rb_ary_each(VALUE ary);
VALUE rb_ary_join(VALUE ary, VALUE sep);
VALUE rb_ary_reverse(VALUE ary);
VALUE rb_ary_rotate(VALUE ary, long rot);
VALUE rb_ary_sort(VALUE ary);
VALUE rb_ary_sort_bang(VALUE ary);
VALUE rb_ary_delete(VALUE ary, VALUE elem);
VALUE rb_ary_delete_at(VALUE ary, long pos);
VALUE rb_ary_clear(VALUE ary);
VALUE rb_ary_plus(VALUE lhs, VALUE rhs);
VALUE rb_ary_concat(VALUE lhs, VALUE rhs);
VALUE rb_ary_assoc(VALUE alist, VALUE key);
VALUE rb_ary_rassoc(VALUE alist, VALUE key);
VALUE rb_ary_includes(VALUE ary, VALUE elem);
VALUE rb_ary_cmp(VALUE lhs, VALUE rhs);
VALUE rb_ary_replace(VALUE copy, VALUE orig);
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func)(VALUE obj, long oidx));
VALUE rb_ary_resize(VALUE ary, long len);
VALUE rb_exc_new(VALUE etype, const char *ptr, long len);
__attribute__((__nonnull__ ()))
VALUE rb_exc_new_cstr(VALUE etype, const char *str);
VALUE rb_exc_new_str(VALUE etype, VALUE str);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
void rb_loaderror(const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_loaderror_with_path(VALUE path, const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_name_error(ID name, const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_name_error_str(VALUE name, const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
void rb_frozen_error_raise(VALUE recv, const char *fmt, ...);
__attribute__((__noreturn__))
__attribute__((__nonnull__ ()))
void rb_invalid_str(const char *str, const char *type);
__attribute__((__noreturn__))
__attribute__((__nonnull__ ()))
void rb_error_frozen(const char *what);
__attribute__((__noreturn__))
void rb_error_frozen_object(VALUE what);
void rb_check_frozen(VALUE obj);
void rb_check_copyable(VALUE obj, VALUE orig);
__attribute__((__noreturn__))
static void rb_error_arity(int argc, int min, int max);
static inline void
rb_check_frozen_inline(VALUE obj)
{
if ((__builtin_expect(!!(RB_OBJ_FROZEN(obj)), 0))) {
rb_error_frozen_object(obj);
}
}
static inline int
rb_check_arity(int argc, int min, int max)
{
if ((argc < min) || (max != (-1) && argc > max))
rb_error_arity(argc, min, max);
return argc;
}
__attribute__((__nonnull__ ()))
void rb_st_foreach_safe(struct st_table *st, st_foreach_callback_func *func, st_data_t arg);
VALUE rb_check_hash_type(VALUE obj);
__attribute__((__nonnull__ ()))
void rb_hash_foreach(VALUE hash, int (*func)(VALUE key, VALUE val, VALUE arg), VALUE arg);
VALUE rb_hash(VALUE obj);
VALUE rb_hash_new(void);
VALUE rb_hash_new_capa(long capa);
VALUE rb_hash_dup(VALUE hash);
VALUE rb_hash_freeze(VALUE obj);
VALUE rb_hash_aref(VALUE hash, VALUE key);
VALUE rb_hash_lookup(VALUE hash, VALUE key);
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def);
VALUE rb_hash_fetch(VALUE hash, VALUE key);
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val);
VALUE rb_hash_clear(VALUE hash);
VALUE rb_hash_delete_if(VALUE hash);
VALUE rb_hash_delete(VALUE hash, VALUE key);
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash);
typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);
int rb_path_check(const char *path);
VALUE rb_env_clear(void);
VALUE rb_hash_size(VALUE hash);
VALUE rb_block_proc(void);
VALUE rb_block_lambda(void);
VALUE rb_proc_new(rb_block_call_func_t func, VALUE callback_arg);
VALUE rb_obj_is_proc(VALUE recv);
VALUE rb_proc_call(VALUE recv, VALUE args);
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat);
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc);
VALUE rb_proc_call_with_block_kw(VALUE recv, int argc, const VALUE *argv, VALUE proc, int kw_splat);
int rb_proc_arity(VALUE recv);
VALUE rb_proc_lambda_p(VALUE recv);
VALUE rb_binding_new(void);
VALUE rb_obj_method(VALUE recv, VALUE mid);
VALUE rb_obj_is_method(VALUE recv);
VALUE rb_method_call(int argc, const VALUE *argv, VALUE recv);
VALUE rb_method_call_kw(int argc, const VALUE *argv, VALUE recv, int kw_splat);
VALUE rb_method_call_with_block(int argc, const VALUE *argv, VALUE recv, VALUE proc);
VALUE rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE recv, VALUE proc, int kw_splat);
int rb_mod_method_arity(VALUE mod, ID mid);
int rb_obj_method_arity(VALUE obj, ID mid);
__attribute__((__nonnull__ (1)))
VALUE rb_protect(VALUE (*func)(VALUE args), VALUE args, int *state);
__attribute__((__nonnull__ (2, 3)))
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...);
__attribute__((__nonnull__ (3, 4)))
int rb_scan_args_kw(int kw_splat, int argc, const VALUE *argv, const char *fmt, ...);
__attribute__((__error__ ("bad scan arg format")))
void rb_scan_args_bad_format(const char*);
__attribute__((__error__ ("variable argument length doesn't match")))
void rb_scan_args_length_mismatch(const char*,int);
static inline _Bool
rb_scan_args_keyword_p(int kw_flag, VALUE last)
{
switch (kw_flag) {
case 0:
return !! rb_keyword_given_p();
case 1:
return 1;
case 3:
return RB_TYPE_P(last, RUBY_T_HASH);
default:
return 0;
}
}
__attribute__((__always_inline__)) inline
static _Bool
rb_scan_args_lead_p(const char *fmt)
{
return (((unsigned char)((fmt[0])-'0'))<10);
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_n_lead(const char *fmt)
{
return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
}
__attribute__((__always_inline__)) inline
static _Bool
rb_scan_args_opt_p(const char *fmt)
{
return (rb_scan_args_lead_p(fmt) && (((unsigned char)((fmt[1])-'0'))<10));
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_n_opt(const char *fmt)
{
return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_var_idx(const char *fmt)
{
return (!rb_scan_args_lead_p(fmt) ? 0 : !(((unsigned char)((fmt[1])-'0'))<10) ? 1 : 2);
}
__attribute__((__always_inline__)) inline
static _Bool
rb_scan_args_f_var(const char *fmt)
{
return (fmt[rb_scan_args_var_idx(fmt)]=='*');
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_trail_idx(const char *fmt)
{
const int idx = rb_scan_args_var_idx(fmt);
return idx+(fmt[idx]=='*');
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_n_trail(const char *fmt)
{
const int idx = rb_scan_args_trail_idx(fmt);
return ((((unsigned char)((fmt[idx])-'0'))<10) ? fmt[idx]-'0' : 0);
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_hash_idx(const char *fmt)
{
const int idx = rb_scan_args_trail_idx(fmt);
return idx+(((unsigned char)((fmt[idx])-'0'))<10);
}
__attribute__((__always_inline__)) inline
static _Bool
rb_scan_args_f_hash(const char *fmt)
{
return (fmt[rb_scan_args_hash_idx(fmt)]==':');
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_block_idx(const char *fmt)
{
const int idx = rb_scan_args_hash_idx(fmt);
return idx+(fmt[idx]==':');
}
__attribute__((__always_inline__)) inline
static _Bool
rb_scan_args_f_block(const char *fmt)
{
return (fmt[rb_scan_args_block_idx(fmt)]=='&');
}
__attribute__((__always_inline__)) inline
static int
rb_scan_args_set(int kw_flag, int argc, const VALUE *argv,
int n_lead, int n_opt, int n_trail,
_Bool f_var, _Bool f_hash, _Bool f_block,
VALUE *vars[], const char *fmt __attribute__((__unused__)), int varc __attribute__((__unused__)))
{
int i, argi = 0, vari = 0;
VALUE *var, hash = ((VALUE)RUBY_Qnil);
const int n_mand = n_lead + n_trail;
if (f_hash && argc > 0) {
VALUE last = argv[argc - 1];
if (rb_scan_args_keyword_p(kw_flag, last)) {
hash = rb_hash_dup(last);
argc--;
}
}
if (argc < n_mand) {
goto argc_error;
}
for (i = 0; i < n_lead; i++) {
var = vars[vari++];
if (var) *var = argv[argi];
argi++;
}
for (i = 0; i < n_opt; i++) {
var = vars[vari++];
if (argi < argc - n_trail) {
if (var) *var = argv[argi];
argi++;
}
else {
if (var) *var = ((VALUE)RUBY_Qnil);
}
}
if (f_var) {
int n_var = argc - argi - n_trail;
var = vars[vari++];
if (0 < n_var) {
if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
argi += n_var;
}
else {
if (var) *var = rb_ary_new();
}
}
for (i = 0; i < n_trail; i++) {
var = vars[vari++];
if (var) *var = argv[argi];
argi++;
}
if (f_hash) {
var = vars[vari++];
if (var) *var = hash;
}
if (f_block) {
var = vars[vari++];
if (rb_block_given_p()) {
*var = rb_block_proc();
}
else {
*var = ((VALUE)RUBY_Qnil);
}
}
if (argi == argc) {
return argc;
}
argc_error:
rb_error_arity(argc, n_mand, f_var ? (-1) : n_mand + n_opt);
__builtin_unreachable();
}
ID rb_sym2id(VALUE obj);
VALUE rb_id2sym(ID id);
__attribute__((__nonnull__ ()))
ID rb_intern(const char *name);
ID rb_intern2(const char *name, long len);
ID rb_intern_str(VALUE str);
const char *rb_id2name(ID id);
__attribute__((__nonnull__ ()))
ID rb_check_id(volatile VALUE *namep);
ID rb_to_id(VALUE str);
VALUE rb_id2str(ID id);
VALUE rb_sym2str(VALUE id);
VALUE rb_to_symbol(VALUE name);
__attribute__((__nonnull__ ()))
VALUE rb_check_symbol(volatile VALUE *namep);
__attribute__((__pure__))
__attribute__((__nonnull__ ()))
static inline ID
rb_intern_const(const char *str)
{
size_t len = strlen(str);
return rb_intern2(str, ((long)len));
}
__attribute__((__nonnull__ ()))
static inline ID
rbimpl_intern_const(ID *ptr, const char *str)
{
while (! *ptr) {
*ptr = rb_intern_const(str);
}
return *ptr;
}
typedef VALUE rb_gvar_getter_t(ID id, VALUE *data);
typedef void rb_gvar_setter_t(VALUE val, ID id, VALUE *data);
typedef void rb_gvar_marker_t(VALUE *var);
rb_gvar_getter_t rb_gvar_undef_getter;
rb_gvar_setter_t rb_gvar_undef_setter;
rb_gvar_marker_t rb_gvar_undef_marker;
rb_gvar_getter_t rb_gvar_val_getter;
rb_gvar_setter_t rb_gvar_val_setter;
rb_gvar_marker_t rb_gvar_val_marker;
rb_gvar_getter_t rb_gvar_var_getter;
rb_gvar_setter_t rb_gvar_var_setter;
rb_gvar_marker_t rb_gvar_var_marker;
__attribute__((__noreturn__))
rb_gvar_setter_t rb_gvar_readonly_setter;
__attribute__((__nonnull__ ()))
void rb_define_variable(const char *name, VALUE *var);
__attribute__((__nonnull__ (1)))
void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);
__attribute__((__nonnull__ (1)))
void rb_define_hooked_variable(const char *name, VALUE *var, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);
__attribute__((__nonnull__ ()))
void rb_define_readonly_variable(const char *name, const VALUE *var);
__attribute__((__nonnull__ ()))
void rb_define_const(VALUE klass, const char *name, VALUE val);
__attribute__((__nonnull__ ()))
void rb_define_global_const(const char *name, VALUE val);
__attribute__((__nonnull__ ()))
void rb_deprecate_constant(VALUE mod, const char *name);
__attribute__((__nonnull__ ()))
VALUE rb_gv_set(const char *name, VALUE val);
__attribute__((__nonnull__ ()))
VALUE rb_gv_get(const char *name);
__attribute__((__nonnull__ ()))
VALUE rb_iv_get(VALUE obj, const char *name);
__attribute__((__nonnull__ ()))
VALUE rb_iv_set(VALUE obj, const char *name, VALUE val);
VALUE rb_get_path(VALUE obj);
VALUE rb_get_path_no_checksafe(VALUE);
__attribute__((__error__ (" argument length doesn't match"))) int rb_varargs_bad_length(int,int);
const char *rb_class2name(VALUE klass);
const char *rb_obj_classname(VALUE obj);
void rb_p(VALUE obj);
VALUE rb_equal(VALUE lhs, VALUE rhs);
VALUE rb_require(const char *feature);
VALUE rb_big_new(size_t len, int sign);
int rb_bigzero_p(VALUE x);
VALUE rb_big_clone(VALUE num);
void rb_big_2comp(VALUE num);
VALUE rb_big_norm(VALUE x);
void rb_big_resize(VALUE big, size_t len);
__attribute__((__nonnull__ ()))
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck);
VALUE rb_str_to_inum(VALUE str, int base, int badcheck);
__attribute__((__nonnull__ ()))
VALUE rb_cstr2inum(const char *str, int base);
VALUE rb_str2inum(VALUE str, int base);
VALUE rb_big2str(VALUE x, int base);
long rb_big2long(VALUE x);
unsigned long rb_big2ulong(VALUE x);
long long rb_big2ll(VALUE);
unsigned long long rb_big2ull(VALUE);
__attribute__((__nonnull__ ()))
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);
__attribute__((__nonnull__ ()))
VALUE rb_big_unpack(unsigned long *buf, long num_longs);
__attribute__((__nonnull__ ()))
int rb_uv_to_utf8(char buf[6], unsigned long uv);
VALUE rb_dbl2big(double d);
double rb_big2dbl(VALUE x);
VALUE rb_big_cmp(VALUE lhs, VALUE rhs);
VALUE rb_big_eq(VALUE lhs, VALUE rhs);
VALUE rb_big_eql(VALUE lhs, VALUE rhs);
VALUE rb_big_plus(VALUE x, VALUE y);
VALUE rb_big_minus(VALUE x, VALUE y);
VALUE rb_big_mul(VALUE x, VALUE y);
VALUE rb_big_div(VALUE x, VALUE y);
VALUE rb_big_idiv(VALUE x, VALUE y);
VALUE rb_big_modulo(VALUE x, VALUE y);
VALUE rb_big_divmod(VALUE x, VALUE y);
VALUE rb_big_pow(VALUE x, VALUE y);
VALUE rb_big_and(VALUE x, VALUE y);
VALUE rb_big_or(VALUE x, VALUE y);
VALUE rb_big_xor(VALUE x, VALUE y);
VALUE rb_big_lshift(VALUE x, VALUE y);
VALUE rb_big_rshift(VALUE x, VALUE y);
__attribute__((__nonnull__ ()))
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
__attribute__((__nonnull__ ()))
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
int rb_absint_singlebit_p(VALUE val);
int rb_cmpint(VALUE val, VALUE a, VALUE b);
__attribute__((__cold__))
__attribute__((__noreturn__))
void rb_cmperr(VALUE a, VALUE b);
VALUE rb_complex_raw(VALUE real, VALUE imag);
VALUE rb_complex_new(VALUE real, VALUE imag);
VALUE rb_complex_new_polar(VALUE abs, VALUE arg);
__attribute__((__deprecated__ ("by: rb_complex_new_polar")))
VALUE rb_complex_polar(VALUE abs, VALUE arg);
__attribute__((__pure__))
VALUE rb_complex_real(VALUE z);
__attribute__((__pure__))
VALUE rb_complex_imag(VALUE z);
VALUE rb_complex_plus(VALUE x, VALUE y);
VALUE rb_complex_minus(VALUE x, VALUE y);
VALUE rb_complex_mul(VALUE x, VALUE y);
VALUE rb_complex_div(VALUE x, VALUE y);
VALUE rb_complex_uminus(VALUE z);
VALUE rb_complex_conjugate(VALUE z);
VALUE rb_complex_abs(VALUE z);
VALUE rb_complex_arg(VALUE z);
VALUE rb_complex_pow(VALUE base, VALUE exp);
VALUE rb_dbl_complex_new(double real, double imag);
VALUE rb_Complex(VALUE real, VALUE imag);
VALUE rb_fiber_new(rb_block_call_func_t func, VALUE callback_obj);
VALUE rb_fiber_new_storage(rb_block_call_func_t func, VALUE callback_obj, VALUE storage);
VALUE rb_fiber_current(void);
VALUE rb_fiber_alive_p(VALUE fiber);
VALUE rb_obj_is_fiber(VALUE obj);
VALUE rb_fiber_resume(VALUE fiber, int argc, const VALUE *argv);
VALUE rb_fiber_resume_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);
VALUE rb_fiber_yield(int argc, const VALUE *argv);
VALUE rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat);
VALUE rb_fiber_transfer(VALUE fiber, int argc, const VALUE *argv);
VALUE rb_fiber_transfer_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);
VALUE rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv);
VALUE rb_dir_getwd(void);
VALUE rb_enum_values_pack(int argc, const VALUE *argv);
__attribute__((__noreturn__))
void rb_exc_raise(VALUE exc);
__attribute__((__noreturn__))
void rb_exc_fatal(VALUE exc);
__attribute__((__noreturn__))
VALUE rb_f_exit(int argc, const VALUE *argv);
__attribute__((__noreturn__))
VALUE rb_f_abort(int argc, const VALUE *argv);
__attribute__((__noreturn__))
void rb_interrupt(void);
ID rb_frame_this_func(void);
__attribute__((__noreturn__))
void rb_jump_tag(int state);
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv);
void rb_obj_call_init_kw(VALUE, int, const VALUE*, int);
ID rb_frame_callee(void);
VALUE rb_make_exception(int argc, const VALUE *argv);
void rb_set_end_proc(void (*func)(VALUE arg), VALUE arg);
typedef VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj);
typedef struct {
VALUE begin;
VALUE end;
VALUE step;
int exclude_end;
} rb_arithmetic_sequence_components_t;
VALUE rb_enumeratorize(VALUE recv, VALUE meth, int argc, const VALUE *argv);
VALUE rb_enumeratorize_with_size(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func);
VALUE rb_enumeratorize_with_size_kw(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func, int kw_splat);
__attribute__((__nonnull__ ()))
int rb_arithmetic_sequence_extract(VALUE as, rb_arithmetic_sequence_components_t *buf);
__attribute__((__nonnull__ ()))
VALUE rb_arithmetic_sequence_beg_len_step(VALUE as, long *begp, long *lenp, long *stepp, long len, int err);
__attribute__((__nonnull__ ()))
VALUE rb_file_s_expand_path(int argc, const VALUE *argv);
VALUE rb_file_expand_path(VALUE fname, VALUE dname);
__attribute__((__nonnull__ ()))
VALUE rb_file_s_absolute_path(int argc, const VALUE *argv);
VALUE rb_file_absolute_path(VALUE fname, VALUE dname);
VALUE rb_file_dirname(VALUE fname);
__attribute__((__nonnull__ ()))
int rb_find_file_ext(VALUE *feature, const char *const *exts);
VALUE rb_find_file(VALUE path);
VALUE rb_file_directory_p(VALUE _, VALUE path);
VALUE rb_str_encode_ospath(VALUE path);
__attribute__((__nonnull__ ()))
__attribute__((__pure__))
int rb_is_absolute_path(const char *path);
off_t rb_file_size(VALUE file);
__attribute__((__cold__))
__attribute__((__noreturn__))
void rb_memerror(void);
__attribute__((__pure__))
int rb_during_gc(void);
__attribute__((__nonnull__ (1)))
void rb_gc_mark_locations(const VALUE *start, const VALUE *end);
void rb_mark_tbl(struct st_table *tbl);
void rb_mark_tbl_no_pin(struct st_table *tbl);
void rb_mark_set(struct st_table *tbl);
void rb_mark_hash(struct st_table *tbl);
void rb_gc_update_tbl_refs(st_table *ptr);
void rb_gc_mark_maybe(VALUE obj);
void rb_gc_mark(VALUE obj);
void rb_gc_mark_movable(VALUE obj);
VALUE rb_gc_location(VALUE obj);
__attribute__((__deprecated__ ("this is now a no-op function")))
void rb_gc_force_recycle(VALUE obj);
void rb_gc(void);
void rb_gc_copy_finalizer(VALUE dst, VALUE src);
VALUE rb_gc_enable(void);
VALUE rb_gc_disable(void);
VALUE rb_gc_start(void);
VALUE rb_define_finalizer(VALUE obj, VALUE block);
VALUE rb_undefine_finalizer(VALUE obj);
size_t rb_gc_count(void);
size_t rb_gc_stat(VALUE key_or_buf);
VALUE rb_gc_latest_gc_info(VALUE key_or_buf);
void rb_gc_adjust_memory_usage(ssize_t diff);
extern VALUE rb_fs;
extern VALUE rb_output_fs;
extern VALUE rb_rs;
extern VALUE rb_default_rs;
extern VALUE rb_output_rs;
VALUE rb_io_write(VALUE io, VALUE str);
VALUE rb_io_gets(VALUE io);
VALUE rb_io_getbyte(VALUE io);
VALUE rb_io_ungetc(VALUE io, VALUE c);
VALUE rb_io_ungetbyte(VALUE io, VALUE b);
VALUE rb_io_close(VALUE io);
VALUE rb_io_flush(VALUE io);
VALUE rb_io_eof(VALUE io);
VALUE rb_io_binmode(VALUE io);
VALUE rb_io_ascii8bit_binmode(VALUE io);
VALUE rb_io_addstr(VALUE io, VALUE str);
VALUE rb_io_printf(int argc, const VALUE *argv, VALUE io);
VALUE rb_io_print(int argc, const VALUE *argv, VALUE io);
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE io);
VALUE rb_io_fdopen(int fd, int flags, const char *path);
__attribute__((__nonnull__ ()))
VALUE rb_file_open(const char *fname, const char *fmode);
__attribute__((__nonnull__ ()))
VALUE rb_file_open_str(VALUE fname, const char *fmode);
VALUE rb_gets(void);
__attribute__((__nonnull__ ()))
void rb_write_error(const char *str);
void rb_write_error2(const char *str, long len);
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
__attribute__((__nonnull__ ()))
int rb_pipe(int *pipes);
int rb_reserved_fd_p(int fd);
int rb_cloexec_open(const char *pathname, int flags, mode_t mode);
int rb_cloexec_dup(int oldfd);
int rb_cloexec_dup2(int oldfd, int newfd);
__attribute__((__nonnull__ ()))
int rb_cloexec_pipe(int fildes[2]);
int rb_cloexec_fcntl_dupfd(int fd, int minfd);
void rb_update_max_fd(int fd);
void rb_fd_fix_cloexec(int fd);
void rb_load(VALUE path, int wrap);
void rb_load_protect(VALUE path, int wrap, int *state);
__attribute__((__nonnull__ ()))
int rb_provided(const char *feature);
__attribute__((__nonnull__ (1)))
int rb_feature_provided(const char *feature, const char **loading);
__attribute__((__nonnull__ ()))
void rb_provide(const char *feature);
VALUE rb_f_require(VALUE self, VALUE feature);
VALUE rb_require_string(VALUE feature);
void rb_ext_ractor_safe(_Bool flag);
VALUE rb_marshal_dump(VALUE obj, VALUE port);
VALUE rb_marshal_load(VALUE port);
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));
__attribute__((__noreturn__))
__attribute__((__cold__))
void rb_num_zerodiv(void);
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op);
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op);
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op);
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op);
VALUE rb_num2fix(VALUE val);
VALUE rb_fix2str(VALUE val, int base);
__attribute__((__const__))
VALUE rb_dbl_cmp(double lhs, double rhs);
extern VALUE rb_int_positive_pow(long x, unsigned long y);
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass);
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass);
VALUE rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_splat);
int rb_eql(VALUE lhs, VALUE rhs);
VALUE rb_any_to_s(VALUE obj);
VALUE rb_inspect(VALUE obj);
VALUE rb_obj_is_instance_of(VALUE obj, VALUE klass);
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);
VALUE rb_obj_alloc(VALUE klass);
VALUE rb_obj_clone(VALUE obj);
VALUE rb_obj_dup(VALUE obj);
VALUE rb_obj_init_copy(VALUE src, VALUE dst);
VALUE rb_obj_freeze(VALUE obj);
__attribute__((__pure__))
VALUE rb_obj_frozen_p(VALUE obj);
VALUE rb_obj_id(VALUE obj);
__attribute__((__const__))
VALUE rb_memory_id(VALUE obj);
__attribute__((__pure__))
VALUE rb_class_real(VALUE klass);
__attribute__((__pure__))
VALUE rb_class_inherited_p(VALUE scion, VALUE ascendant);
__attribute__((__pure__))
VALUE rb_class_superclass(VALUE klass);
__attribute__((__nonnull__ ()))
VALUE rb_convert_type(VALUE val, int type, const char *name, const char *mid);
__attribute__((__nonnull__ ()))
VALUE rb_check_convert_type(VALUE val, int type, const char *name, const char *mid);
__attribute__((__nonnull__ ()))
VALUE rb_check_to_integer(VALUE val, const char *mid);
VALUE rb_check_to_float(VALUE val);
VALUE rb_to_int(VALUE val);
VALUE rb_check_to_int(VALUE val);
VALUE rb_Integer(VALUE val);
VALUE rb_to_float(VALUE val);
VALUE rb_Float(VALUE val);
VALUE rb_String(VALUE val);
VALUE rb_Array(VALUE val);
VALUE rb_Hash(VALUE val);
__attribute__((__nonnull__ ()))
double rb_cstr_to_dbl(const char *str, int mode);
double rb_str_to_dbl(VALUE str, int mode);
ID rb_id_attrset(ID id);
__attribute__((__const__))
int rb_is_const_id(ID id);
__attribute__((__const__))
int rb_is_global_id(ID id);
__attribute__((__const__))
int rb_is_instance_id(ID id);
__attribute__((__const__))
int rb_is_attrset_id(ID id);
__attribute__((__const__))
int rb_is_class_id(ID id);
__attribute__((__const__))
int rb_is_local_id(ID id);
__attribute__((__const__))
int rb_is_junk_id(ID);
__attribute__((__nonnull__ ()))
int rb_symname_p(const char *str);
VALUE rb_backref_get(void);
void rb_backref_set(VALUE md);
VALUE rb_lastline_get(void);
void rb_lastline_set(VALUE str);
VALUE rb_sym_all_symbols(void);
void rb_last_status_set(int status, pid_t pid);
VALUE rb_last_status_get(void);
__attribute__((__nonnull__ ()))
int rb_proc_exec(const char *cmd);
__attribute__((__noreturn__))
VALUE rb_f_exec(int argc, const VALUE *argv);
pid_t rb_waitpid(pid_t pid, int *status, int flags);
void rb_syswait(pid_t pid);
pid_t rb_spawn(int argc, const VALUE *argv);
pid_t rb_spawn_err(int argc, const VALUE *argv, char *errbuf, size_t buflen);
VALUE rb_proc_times(VALUE _);
VALUE rb_detach_process(pid_t pid);
unsigned int rb_genrand_int32(void);
double rb_genrand_real(void);
void rb_reset_random_seed(void);
VALUE rb_random_bytes(VALUE rnd, long n);
unsigned int rb_random_int32(VALUE rnd);
double rb_random_real(VALUE rnd);
unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit);
unsigned long rb_genrand_ulong_limited(unsigned long i);
VALUE rb_range_new(VALUE beg, VALUE end, int excl);
__attribute__((__nonnull__ ()))
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err);
__attribute__((__nonnull__ ()))
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);
VALUE rb_rational_raw(VALUE num, VALUE den);
VALUE rb_rational_new(VALUE num, VALUE den);
VALUE rb_Rational(VALUE num, VALUE den);
__attribute__((__pure__))
VALUE rb_rational_num(VALUE rat);
__attribute__((__pure__))
VALUE rb_rational_den(VALUE rat);
VALUE rb_flt_rationalize_with_prec(VALUE flt, VALUE prec);
VALUE rb_flt_rationalize(VALUE flt);
int rb_memcicmp(const void *s1,const void *s2, long n);
void rb_match_busy(VALUE md);
VALUE rb_reg_nth_defined(int n, VALUE md);
VALUE rb_reg_nth_match(int n, VALUE md);
int rb_reg_backref_number(VALUE match, VALUE backref);
VALUE rb_reg_last_match(VALUE md);
VALUE rb_reg_match_pre(VALUE md);
VALUE rb_reg_match_post(VALUE md);
VALUE rb_reg_match_last(VALUE md);
VALUE rb_reg_new_str(VALUE src, int opts);
__attribute__((__nonnull__ ()))
VALUE rb_reg_new(const char *src, long len, int opts);
VALUE rb_reg_alloc(void);
VALUE rb_reg_init_str(VALUE re, VALUE s, int options);
VALUE rb_reg_match(VALUE re, VALUE str);
VALUE rb_reg_match2(VALUE re);
int rb_reg_options(VALUE re);
extern VALUE rb_argv0;
VALUE rb_get_argv(void);
__attribute__((__nonnull__ ()))
void *rb_load_file(const char *file);
void *rb_load_file_str(VALUE file);
struct timeval;
typedef struct {
int maxfd;
fd_set *fdset;
} rb_fdset_t;
__attribute__((__nonnull__ ()))
void rb_fd_init(rb_fdset_t *f);
__attribute__((__nonnull__ ()))
void rb_fd_term(rb_fdset_t *f);
__attribute__((__nonnull__ ()))
void rb_fd_zero(rb_fdset_t *f);
__attribute__((__nonnull__ ()))
void rb_fd_set(int fd, rb_fdset_t *f);
__attribute__((__nonnull__ ()))
void rb_fd_clr(int fd, rb_fdset_t *f);
__attribute__((__nonnull__ ()))
__attribute__((__pure__))
int rb_fd_isset(int fd, const rb_fdset_t *f);
void rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int max);
void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
int rb_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
__attribute__((__nonnull__ ()))
__attribute__((__pure__))
static inline fd_set *
rb_fd_ptr(const rb_fdset_t *f)
{
return f->fdset;
}
__attribute__((__nonnull__ ()))
__attribute__((__pure__))
static inline int
rb_fd_max(const rb_fdset_t *f)
{
return f->maxfd;
}
struct timeval;
int rb_thread_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
__attribute__((__nonnull__ ()))
VALUE rb_f_kill(int argc, const VALUE *argv);
void (*ruby_posix_signal(int, void (*)(int)))(int);
__attribute__((__pure__))
const char *ruby_signal_name(int signo);
void ruby_default_signal(int sig);
VALUE rb_f_sprintf(int argc, const VALUE *argv);
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 2)))
VALUE rb_sprintf(const char *fmt, ...);
__attribute__((__nonnull__ (1)))
__attribute__((__format__(__printf__, 1, 0)))
VALUE rb_vsprintf(const char *fmt, va_list ap);
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
VALUE rb_str_catf(VALUE dst, const char *fmt, ...);
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 0)))
VALUE rb_str_vcatf(VALUE dst, const char *fmt, va_list ap);
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt);
VALUE rb_str_new(const char *ptr, long len);
VALUE rb_str_new_cstr(const char *ptr);
VALUE rb_str_new_shared(VALUE str);
VALUE rb_str_new_frozen(VALUE str);
VALUE rb_str_new_with_class(VALUE obj, const char *ptr, long len);
VALUE rb_external_str_new(const char *ptr, long len);
__attribute__((__nonnull__ ()))
VALUE rb_external_str_new_cstr(const char *ptr);
VALUE rb_locale_str_new(const char *ptr, long len);
__attribute__((__nonnull__ ()))
VALUE rb_locale_str_new_cstr(const char *ptr);
VALUE rb_filesystem_str_new(const char *ptr, long len);
__attribute__((__nonnull__ ()))
VALUE rb_filesystem_str_new_cstr(const char *ptr);
VALUE rb_str_buf_new(long capa);
__attribute__((__nonnull__ ()))
VALUE rb_str_buf_new_cstr(const char *ptr);
VALUE rb_str_tmp_new(long len);
VALUE rb_usascii_str_new(const char *ptr, long len);
VALUE rb_usascii_str_new_cstr(const char *ptr);
VALUE rb_utf8_str_new(const char *ptr, long len);
VALUE rb_utf8_str_new_cstr(const char *ptr);
VALUE rb_str_new_static(const char *ptr, long len);
VALUE rb_usascii_str_new_static(const char *ptr, long len);
VALUE rb_utf8_str_new_static(const char *ptr, long len);
VALUE rb_str_to_interned_str(VALUE str);
VALUE rb_interned_str(const char *ptr, long len);
__attribute__((__nonnull__ ()))
VALUE rb_interned_str_cstr(const char *ptr);
void rb_str_free(VALUE str);
void rb_str_shared_replace(VALUE dst, VALUE src);
VALUE rb_str_buf_append(VALUE dst, VALUE src);
VALUE rb_str_buf_cat(VALUE, const char*, long);
VALUE rb_str_buf_cat2(VALUE, const char*);
__attribute__((__nonnull__ ()))
VALUE rb_str_buf_cat_ascii(VALUE dst, const char *src);
VALUE rb_obj_as_string(VALUE obj);
VALUE rb_check_string_type(VALUE obj);
void rb_must_asciicompat(VALUE obj);
VALUE rb_str_dup(VALUE str);
VALUE rb_str_resurrect(VALUE str);
VALUE rb_str_locktmp(VALUE str);
VALUE rb_str_unlocktmp(VALUE str);
VALUE rb_str_dup_frozen(VALUE);
VALUE rb_str_plus(VALUE lhs, VALUE rhs);
VALUE rb_str_times(VALUE str, VALUE num);
long rb_str_sublen(VALUE str, long pos);
VALUE rb_str_substr(VALUE str, long beg, long len);
VALUE rb_str_subseq(VALUE str, long beg, long len);
char *rb_str_subpos(VALUE str, long beg, long *len);
void rb_str_modify(VALUE str);
void rb_str_modify_expand(VALUE str, long capa);
VALUE rb_str_freeze(VALUE str);
void rb_str_set_len(VALUE str, long len);
VALUE rb_str_resize(VALUE str, long len);
VALUE rb_str_cat(VALUE dst, const char *src, long srclen);
VALUE rb_str_cat_cstr(VALUE dst, const char *src);
VALUE rb_str_cat2(VALUE, const char*);
VALUE rb_str_append(VALUE dst, VALUE src);
VALUE rb_str_concat(VALUE dst, VALUE src);
st_index_t rb_memhash(const void *ptr, long len);
st_index_t rb_hash_start(st_index_t i);
st_index_t rb_str_hash(VALUE str);
int rb_str_hash_cmp(VALUE str1, VALUE str2);
int rb_str_comparable(VALUE str1, VALUE str2);
int rb_str_cmp(VALUE lhs, VALUE rhs);
VALUE rb_str_equal(VALUE str1, VALUE str2);
VALUE rb_str_drop_bytes(VALUE str, long len);
void rb_str_update(VALUE dst, long beg, long len, VALUE src);
VALUE rb_str_replace(VALUE dst, VALUE src);
VALUE rb_str_inspect(VALUE str);
VALUE rb_str_dump(VALUE str);
VALUE rb_str_split(VALUE str, const char *delim);
rb_gvar_setter_t rb_str_setter;
VALUE rb_str_intern(VALUE str);
VALUE rb_sym_to_s(VALUE sym);
long rb_str_strlen(VALUE str);
VALUE rb_str_length(VALUE);
long rb_str_offset(VALUE str, long pos);
__attribute__((__pure__))
size_t rb_str_capacity(VALUE str);
VALUE rb_str_ellipsize(VALUE str, long len);
VALUE rb_str_scrub(VALUE str, VALUE repl);
VALUE rb_str_succ(VALUE orig);
__attribute__((__nonnull__ ()))
static inline long
rbimpl_strlen(const char *str)
{
return ((long)strlen(str));
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_str_new_static(str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_usascii_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_usascii_str_new_static(str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_utf8_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_utf8_str_new_static(str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_external_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_external_str_new(str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_locale_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_locale_str_new(str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_str_buf_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
VALUE buf = rb_str_buf_new(len);
return rb_str_buf_cat(buf, str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_str_cat_cstr(VALUE buf, const char *str)
{
long len = rbimpl_strlen(str);
return rb_str_cat(buf, str, len);
}
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_exc_new_cstr(VALUE exc, const char *str)
{
long len = rbimpl_strlen(str);
return rb_exc_new(exc, str, len);
}
VALUE rb_struct_new(VALUE klass, ...);
VALUE rb_struct_define(const char *name, ...);
__attribute__((__nonnull__ (2)))
VALUE rb_struct_define_under(VALUE space, const char *name, ...);
VALUE rb_struct_alloc(VALUE klass, VALUE values);
VALUE rb_struct_initialize(VALUE self, VALUE values);
VALUE rb_struct_getmember(VALUE self, ID key);
VALUE rb_struct_s_members(VALUE klass);
VALUE rb_struct_members(VALUE self);
VALUE rb_struct_alloc_noinit(VALUE klass);
VALUE rb_struct_define_without_accessor(const char *name, VALUE super, rb_alloc_func_t func, ...);
__attribute__((__nonnull__ (2)))
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
struct timeval;
void rb_thread_schedule(void);
int rb_thread_wait_fd(int fd);
int rb_thread_fd_writable(int fd);
void rb_thread_fd_close(int fd);
int rb_thread_alone(void);
void rb_thread_sleep(int sec);
void rb_thread_sleep_forever(void);
void rb_thread_sleep_deadly(void);
VALUE rb_thread_stop(void);
VALUE rb_thread_wakeup(VALUE thread);
VALUE rb_thread_wakeup_alive(VALUE thread);
VALUE rb_thread_run(VALUE thread);
VALUE rb_thread_kill(VALUE thread);
__attribute__((__nonnull__ (1)))
VALUE rb_thread_create(VALUE (*f)(void *g), void *g);
void rb_thread_wait_for(struct timeval time);
VALUE rb_thread_current(void);
VALUE rb_thread_main(void);
VALUE rb_thread_local_aref(VALUE thread, ID key);
VALUE rb_thread_local_aset(VALUE thread, ID key, VALUE val);
void rb_thread_atfork(void);
void rb_thread_atfork_before_exec(void);
VALUE rb_exec_recursive(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);
VALUE rb_exec_recursive_paired(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);
VALUE rb_exec_recursive_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);
VALUE rb_exec_recursive_paired_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);
typedef void rb_unblock_function_t(void *);
typedef VALUE rb_blocking_function_t(void *);
void rb_thread_check_ints(void);
int rb_thread_interrupted(VALUE thval);
VALUE rb_mutex_new(void);
VALUE rb_mutex_locked_p(VALUE mutex);
VALUE rb_mutex_trylock(VALUE mutex);
VALUE rb_mutex_lock(VALUE mutex);
VALUE rb_mutex_unlock(VALUE mutex);
VALUE rb_mutex_sleep(VALUE self, VALUE timeout);
VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
struct timespec;
struct timeval;
__attribute__((__nonnull__ ()))
void rb_timespec_now(struct timespec *ts);
VALUE rb_time_new(time_t sec, long usec);
VALUE rb_time_nano_new(time_t sec, long nsec);
__attribute__((__nonnull__ ()))
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);
VALUE rb_time_num_new(VALUE timev, VALUE off);
struct timeval rb_time_interval(VALUE num);
struct timeval rb_time_timeval(VALUE time);
struct timespec rb_time_timespec(VALUE time);
struct timespec rb_time_timespec_interval(VALUE num);
VALUE rb_time_utc_offset(VALUE time);
VALUE rb_mod_name(VALUE mod);
VALUE rb_class_path(VALUE mod);
VALUE rb_class_path_cached(VALUE mod);
__attribute__((__nonnull__ ()))
void rb_set_class_path(VALUE klass, VALUE space, const char *name);
void rb_set_class_path_string(VALUE klass, VALUE space, VALUE name);
VALUE rb_path_to_class(VALUE path);
__attribute__((__nonnull__ ()))
VALUE rb_path2class(const char *path);
VALUE rb_class_name(VALUE obj);
VALUE rb_autoload_load(VALUE space, ID name);
VALUE rb_autoload_p(VALUE space, ID name);
VALUE rb_f_trace_var(int argc, const VALUE *argv);
VALUE rb_f_untrace_var(int argc, const VALUE *argv);
VALUE rb_f_global_variables(void);
void rb_alias_variable(ID dst, ID src);
void rb_free_generic_ivar(VALUE obj);
VALUE rb_ivar_get(VALUE obj, ID name);
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val);
VALUE rb_ivar_defined(VALUE obj, ID name);
void rb_ivar_foreach(VALUE obj, int (*func)(ID name, VALUE val, st_data_t arg), st_data_t arg);
st_index_t rb_ivar_count(VALUE obj);
VALUE rb_attr_get(VALUE obj, ID name);
VALUE rb_obj_instance_variables(VALUE obj);
VALUE rb_obj_remove_instance_variable(VALUE obj, VALUE name);
void *rb_mod_const_at(VALUE, void*);
void *rb_mod_const_of(VALUE, void*);
VALUE rb_const_list(void*);
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv);
VALUE rb_mod_remove_const(VALUE space, VALUE name);
int rb_const_defined(VALUE space, ID name);
int rb_const_defined_at(VALUE space, ID name);
int rb_const_defined_from(VALUE space, ID name);
VALUE rb_const_get(VALUE space, ID name);
VALUE rb_const_get_at(VALUE space, ID name);
VALUE rb_const_get_from(VALUE space, ID name);
void rb_const_set(VALUE space, ID name, VALUE val);
VALUE rb_const_remove(VALUE space, ID name);
VALUE rb_cvar_defined(VALUE klass, ID name);
void rb_cvar_set(VALUE klass, ID name, VALUE val);
VALUE rb_cvar_get(VALUE klass, ID name);
__attribute__((__nonnull__ ()))
VALUE rb_cvar_find(VALUE klass, ID name, VALUE *front);
__attribute__((__nonnull__ ()))
void rb_cv_set(VALUE klass, const char *name, VALUE val);
__attribute__((__nonnull__ ()))
VALUE rb_cv_get(VALUE klass, const char *name);
__attribute__((__nonnull__ ()))
void rb_define_class_variable(VALUE, const char*, VALUE);
VALUE rb_mod_class_variables(int argc, const VALUE *argv, VALUE recv);
VALUE rb_mod_remove_cvar(VALUE mod, VALUE name);
int ruby_native_thread_p(void);
__attribute__((__nonnull__ (3)))
__attribute__((__format__(__printf__, 3, 4)))
int ruby_snprintf(char *str, size_t n, char const *fmt, ...);
__attribute__((__nonnull__ (3)))
__attribute__((__format__(__printf__, 3, 0)))
int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
typedef __sig_atomic_t sig_atomic_t;
union sigval
{
int sival_int;
void *sival_ptr;
};
typedef union sigval __sigval_t;
typedef struct
{
int si_signo;
int si_errno;
int si_code;
int __pad0;
union
{
int _pad[((128 / sizeof (int)) - 4)];
struct
{
__pid_t si_pid;
__uid_t si_uid;
} _kill;
struct
{
int si_tid;
int si_overrun;
__sigval_t si_sigval;
} _timer;
struct
{
__pid_t si_pid;
__uid_t si_uid;
__sigval_t si_sigval;
} _rt;
struct
{
__pid_t si_pid;
__uid_t si_uid;
int si_status;
__clock_t si_utime;
__clock_t si_stime;
} _sigchld;
struct
{
void *si_addr;
short int si_addr_lsb;
union
{
struct
{
void *_lower;
void *_upper;
} _addr_bnd;
__uint32_t _pkey;
} _bounds;
} _sigfault;
struct
{
long int si_band;
int si_fd;
} _sigpoll;
struct
{
void *_call_addr;
int _syscall;
unsigned int _arch;
} _sigsys;
} _sifields;
} siginfo_t ;
enum
{
SI_ASYNCNL = -60,
SI_TKILL = -6,
SI_SIGIO,
SI_ASYNCIO,
SI_MESGQ,
SI_TIMER,
SI_QUEUE,
SI_USER,
SI_KERNEL = 0x80
};
enum
{
ILL_ILLOPC = 1,
ILL_ILLOPN,
ILL_ILLADR,
ILL_ILLTRP,
ILL_PRVOPC,
ILL_PRVREG,
ILL_COPROC,
ILL_BADSTK
};
enum
{
FPE_INTDIV = 1,
FPE_INTOVF,
FPE_FLTDIV,
FPE_FLTOVF,
FPE_FLTUND,
FPE_FLTRES,
FPE_FLTINV,
FPE_FLTSUB
};
enum
{
SEGV_MAPERR = 1,
SEGV_ACCERR,
SEGV_BNDERR,
SEGV_PKUERR
};
enum
{
BUS_ADRALN = 1,
BUS_ADRERR,
BUS_OBJERR,
BUS_MCEERR_AR,
BUS_MCEERR_AO
};
enum
{
TRAP_BRKPT = 1,
TRAP_TRACE
};
enum
{
CLD_EXITED = 1,
CLD_KILLED,
CLD_DUMPED,
CLD_TRAPPED,
CLD_STOPPED,
CLD_CONTINUED
};
enum
{
POLL_IN = 1,
POLL_OUT,
POLL_MSG,
POLL_ERR,
POLL_PRI,
POLL_HUP
};
typedef __sigval_t sigval_t;
typedef struct sigevent
{
__sigval_t sigev_value;
int sigev_signo;
int sigev_notify;
union
{
int _pad[((64 / sizeof (int)) - 4)];
__pid_t _tid;
struct
{
void (*_function) (__sigval_t);
pthread_attr_t *_attribute;
} _sigev_thread;
} _sigev_un;
} sigevent_t;
enum
{
SIGEV_SIGNAL = 0,
SIGEV_NONE,
SIGEV_THREAD,
SIGEV_THREAD_ID = 4
};
typedef void (*__sighandler_t) (int);
extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)
__attribute__ ((__nothrow__ , __leaf__));
extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler)
__attribute__ ((__nothrow__ , __leaf__));
extern __sighandler_t signal (int __sig, __sighandler_t __handler)
__attribute__ ((__nothrow__ , __leaf__));
extern int kill (__pid_t __pid, int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern int killpg (__pid_t __pgrp, int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern int raise (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern __sighandler_t ssignal (int __sig, __sighandler_t __handler)
__attribute__ ((__nothrow__ , __leaf__));
extern int gsignal (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern void psignal (int __sig, const char *__s);
extern void psiginfo (const siginfo_t *__pinfo, const char *__s);
extern int sigpause (int __sig) __asm__ ("__xpg_sigpause");
extern int sigblock (int __mask) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__deprecated__));
extern int sigsetmask (int __mask) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__deprecated__));
extern int siggetmask (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__deprecated__));
typedef __sighandler_t sighandler_t;
typedef __sighandler_t sig_t;
extern int sigemptyset (sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigfillset (sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigaddset (sigset_t *__set, int __signo) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigdelset (sigset_t *__set, int __signo) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigismember (const sigset_t *__set, int __signo)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigisemptyset (const sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigandset (sigset_t *__set, const sigset_t *__left,
const sigset_t *__right) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2, 3)));
extern int sigorset (sigset_t *__set, const sigset_t *__left,
const sigset_t *__right) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2, 3)));
struct sigaction
{
union
{
__sighandler_t sa_handler;
void (*sa_sigaction) (int, siginfo_t *, void *);
}
__sigaction_handler;
__sigset_t sa_mask;
int sa_flags;
void (*sa_restorer) (void);
};
extern int sigprocmask (int __how, const sigset_t *__restrict __set,
sigset_t *__restrict __oset) __attribute__ ((__nothrow__ , __leaf__));
extern int sigsuspend (const sigset_t *__set) __attribute__ ((__nonnull__ (1)));
extern int sigaction (int __sig, const struct sigaction *__restrict __act,
struct sigaction *__restrict __oact) __attribute__ ((__nothrow__ , __leaf__));
extern int sigpending (sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int sigwait (const sigset_t *__restrict __set, int *__restrict __sig)
__attribute__ ((__nonnull__ (1, 2)));
extern int sigwaitinfo (const sigset_t *__restrict __set,
siginfo_t *__restrict __info) __attribute__ ((__nonnull__ (1)));
extern int sigtimedwait (const sigset_t *__restrict __set,
siginfo_t *__restrict __info,
const struct timespec *__restrict __timeout)
__attribute__ ((__nonnull__ (1)));
extern int sigqueue (__pid_t __pid, int __sig, const union sigval __val)
__attribute__ ((__nothrow__ , __leaf__));
extern const char *const _sys_siglist[(64 + 1)];
extern const char *const sys_siglist[(64 + 1)];
struct _fpx_sw_bytes
{
__uint32_t magic1;
__uint32_t extended_size;
__uint64_t xstate_bv;
__uint32_t xstate_size;
__uint32_t __glibc_reserved1[7];
};
struct _fpreg
{
unsigned short significand[4];
unsigned short exponent;
};
struct _fpxreg
{
unsigned short significand[4];
unsigned short exponent;
unsigned short __glibc_reserved1[3];
};
struct _xmmreg
{
__uint32_t element[4];
};
struct _fpstate
{
__uint16_t cwd;
__uint16_t swd;
__uint16_t ftw;
__uint16_t fop;
__uint64_t rip;
__uint64_t rdp;
__uint32_t mxcsr;
__uint32_t mxcr_mask;
struct _fpxreg _st[8];
struct _xmmreg _xmm[16];
__uint32_t __glibc_reserved1[24];
};
struct sigcontext
{
__uint64_t r8;
__uint64_t r9;
__uint64_t r10;
__uint64_t r11;
__uint64_t r12;
__uint64_t r13;
__uint64_t r14;
__uint64_t r15;
__uint64_t rdi;
__uint64_t rsi;
__uint64_t rbp;
__uint64_t rbx;
__uint64_t rdx;
__uint64_t rax;
__uint64_t rcx;
__uint64_t rsp;
__uint64_t rip;
__uint64_t eflags;
unsigned short cs;
unsigned short gs;
unsigned short fs;
unsigned short __pad0;
__uint64_t err;
__uint64_t trapno;
__uint64_t oldmask;
__uint64_t cr2;
__extension__ union
{
struct _fpstate * fpstate;
__uint64_t __fpstate_word;
};
__uint64_t __reserved1 [8];
};
struct _xsave_hdr
{
__uint64_t xstate_bv;
__uint64_t __glibc_reserved1[2];
__uint64_t __glibc_reserved2[5];
};
struct _ymmh_state
{
__uint32_t ymmh_space[64];
};
struct _xstate
{
struct _fpstate fpstate;
struct _xsave_hdr xstate_hdr;
struct _ymmh_state ymmh;
};
extern int sigreturn (struct sigcontext *__scp) __attribute__ ((__nothrow__ , __leaf__));
typedef struct
{
void *ss_sp;
int ss_flags;
size_t ss_size;
} stack_t;
__extension__ typedef long long int greg_t;
typedef greg_t gregset_t[23];
enum
{
REG_R8 = 0,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_RDI,
REG_RSI,
REG_RBP,
REG_RBX,
REG_RDX,
REG_RAX,
REG_RCX,
REG_RSP,
REG_RIP,
REG_EFL,
REG_CSGSFS,
REG_ERR,
REG_TRAPNO,
REG_OLDMASK,
REG_CR2
};
struct _libc_fpxreg
{
unsigned short int significand[4];
unsigned short int exponent;
unsigned short int __glibc_reserved1[3];
};
struct _libc_xmmreg
{
__uint32_t element[4];
};
struct _libc_fpstate
{
__uint16_t cwd;
__uint16_t swd;
__uint16_t ftw;
__uint16_t fop;
__uint64_t rip;
__uint64_t rdp;
__uint32_t mxcsr;
__uint32_t mxcr_mask;
struct _libc_fpxreg _st[8];
struct _libc_xmmreg _xmm[16];
__uint32_t __glibc_reserved1[24];
};
typedef struct _libc_fpstate *fpregset_t;
typedef struct
{
gregset_t gregs;
fpregset_t fpregs;
__extension__ unsigned long long __reserved1 [8];
} mcontext_t;
typedef struct ucontext_t
{
unsigned long int uc_flags;
struct ucontext_t *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
struct _libc_fpstate __fpregs_mem;
__extension__ unsigned long long int __ssp[4];
} ucontext_t;
extern int siginterrupt (int __sig, int __interrupt) __attribute__ ((__nothrow__ , __leaf__));
enum
{
SS_ONSTACK = 1,
SS_DISABLE
};
extern int sigaltstack (const stack_t *__restrict __ss,
stack_t *__restrict __oss) __attribute__ ((__nothrow__ , __leaf__));
struct sigstack
{
void *ss_sp;
int ss_onstack;
};
extern int sigstack (struct sigstack *__ss, struct sigstack *__oss)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__deprecated__));
extern int sighold (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern int sigrelse (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern int sigignore (int __sig) __attribute__ ((__nothrow__ , __leaf__));
extern __sighandler_t sigset (int __sig, __sighandler_t __disp) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_sigmask (int __how,
const __sigset_t *__restrict __newmask,
__sigset_t *__restrict __oldmask)__attribute__ ((__nothrow__ , __leaf__));
extern int pthread_kill (pthread_t __threadid, int __signo) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_sigqueue (pthread_t __threadid, int __signo,
const union sigval __value) __attribute__ ((__nothrow__ , __leaf__));
extern int __libc_current_sigrtmin (void) __attribute__ ((__nothrow__ , __leaf__));
extern int __libc_current_sigrtmax (void) __attribute__ ((__nothrow__ , __leaf__));
typedef long int __jmp_buf[8];
struct __jmp_buf_tag
{
__jmp_buf __jmpbuf;
int __mask_was_saved;
__sigset_t __saved_mask;
};
typedef struct __jmp_buf_tag jmp_buf[1];
extern int setjmp (jmp_buf __env) __attribute__ ((__nothrow__));
extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __attribute__ ((__nothrow__));
extern int _setjmp (struct __jmp_buf_tag __env[1]) __attribute__ ((__nothrow__));
extern void longjmp (struct __jmp_buf_tag __env[1], int __val)
__attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
extern void _longjmp (struct __jmp_buf_tag __env[1], int __val)
__attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
typedef struct __jmp_buf_tag sigjmp_buf[1];
extern void siglongjmp (sigjmp_buf __env, int __val)
__attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
extern void longjmp (struct __jmp_buf_tag __env[1], int __val) __asm__ ("" "__longjmp_chk") __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) __asm__ ("" "__longjmp_chk") __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
extern void siglongjmp (struct __jmp_buf_tag __env[1], int __val) __asm__ ("" "__longjmp_chk") __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__));
static inline char *container_of_or_null_(void *member_ptr, size_t offset)
{
return member_ptr ? (char *)member_ptr - offset : ((void *)0);
}
struct ccan_list_node
{
struct ccan_list_node *next, *prev;
};
struct ccan_list_head
{
struct ccan_list_node n;
};
static inline void ccan_list_head_init(struct ccan_list_head *h)
{
h->n.next = h->n.prev = &h->n;
}
static inline void ccan_list_node_init(struct ccan_list_node *n)
{
n->next = n->prev = n;
}
static inline void ccan_list_add_after_(struct ccan_list_head *h,
struct ccan_list_node *p,
struct ccan_list_node *n,
const char *abortstr)
{
n->next = p->next;
n->prev = p;
p->next->prev = n;
p->next = n;
(void)((void)abortstr, h);
}
static inline void ccan_list_add_(struct ccan_list_head *h,
struct ccan_list_node *n,
const char *abortstr)
{
ccan_list_add_after_(h, &h->n, n, abortstr);
}
static inline void ccan_list_add_before_(struct ccan_list_head *h,
struct ccan_list_node *p,
struct ccan_list_node *n,
const char *abortstr)
{
n->next = p;
n->prev = p->prev;
p->prev->next = n;
p->prev = n;
(void)((void)abortstr, h);
}
static inline void ccan_list_add_tail_(struct ccan_list_head *h,
struct ccan_list_node *n,
const char *abortstr)
{
ccan_list_add_before_(h, &h->n, n, abortstr);
}
static inline int ccan_list_empty_(const struct ccan_list_head *h, const char* abortstr)
{
(void)((void)abortstr, h);
return h->n.next == &h->n;
}
static inline _Bool ccan_list_empty_nocheck(const struct ccan_list_head *h)
{
return h->n.next == &h->n;
}
static inline void ccan_list_del_(struct ccan_list_node *n, const char* abortstr)
{
(void)((void)abortstr, n);
n->next->prev = n->prev;
n->prev->next = n->next;
}
static inline void ccan_list_del_init_(struct ccan_list_node *n, const char *abortstr)
{
ccan_list_del_(n, abortstr);
ccan_list_node_init(n);
}
static inline void ccan_list_del_from(struct ccan_list_head *h, struct ccan_list_node *n)
{
((void) (0));
ccan_list_del_(n, "./ccan/list/list.h" ":" "329");
}
static inline void ccan_list_swap_(struct ccan_list_node *o,
struct ccan_list_node *n,
const char* abortstr)
{
(void)((void)abortstr, o);
*n = *o;
n->next->prev = n;
n->prev->next = n;
}
static inline const void *ccan_list_top_(const struct ccan_list_head *h, size_t off)
{
if (ccan_list_empty_(h, "./ccan/list/list.h" ":" "399"))
return ((void *)0);
return (const char *)h->n.next - off;
}
static inline const void *ccan_list_pop_(const struct ccan_list_head *h, size_t off)
{
struct ccan_list_node *n;
if (ccan_list_empty_(h, "./ccan/list/list.h" ":" "425"))
return ((void *)0);
n = h->n.next;
ccan_list_del_(n, "./ccan/list/list.h" ":" "428");
return (const char *)n - off;
}
static inline const void *ccan_list_tail_(const struct ccan_list_head *h, size_t off)
{
if (ccan_list_empty_(h, "./ccan/list/list.h" ":" "451"))
return ((void *)0);
return (const char *)h->n.prev - off;
}
static inline void ccan_list_append_list_(struct ccan_list_head *to,
struct ccan_list_head *from,
const char *abortstr)
{
struct ccan_list_node *from_tail = ((void)abortstr, from)->n.prev;
struct ccan_list_node *to_tail = ((void)abortstr, to)->n.prev;
to->n.prev = from_tail;
from_tail->next = &to->n;
to_tail->next = &from->n;
from->n.prev = to_tail;
ccan_list_del_(&from->n, "./ccan/list/list.h" ":" "600");
ccan_list_head_init(from);
}
static inline void ccan_list_prepend_list_(struct ccan_list_head *to,
struct ccan_list_head *from,
const char *abortstr)
{
struct ccan_list_node *from_tail = ((void)abortstr, from)->n.prev;
struct ccan_list_node *to_head = ((void)abortstr, to)->n.next;
to->n.next = &from->n;
from->n.prev = &to->n;
to_head->prev = from_tail;
from_tail->next = to_head;
ccan_list_del_(&from->n, "./ccan/list/list.h" ":" "632");
ccan_list_head_init(from);
}
static inline void *ccan_list_node_to_off_(struct ccan_list_node *node, size_t off)
{
return (void *)((char *)node - off);
}
static inline struct ccan_list_node *ccan_list_node_from_off_(void *ptr, size_t off)
{
return (struct ccan_list_node *)((char *)ptr + off);
}
static inline void *ccan_list_entry_or_null(const struct ccan_list_head *h,
const struct ccan_list_node *n,
size_t off)
{
if (n == &h->n)
return ((void *)0);
return (char *)n - off;
}
enum ruby_id_types {
RUBY_ID_STATIC_SYM = 0x01,
RUBY_ID_LOCAL = 0x00,
RUBY_ID_INSTANCE = (0x01<<1),
RUBY_ID_GLOBAL = (0x03<<1),
RUBY_ID_ATTRSET = (0x04<<1),
RUBY_ID_CONST = (0x05<<1),
RUBY_ID_CLASS = (0x06<<1),
RUBY_ID_JUNK = (0x07<<1),
RUBY_ID_INTERNAL = RUBY_ID_JUNK,
RUBY_ID_SCOPE_SHIFT = 4,
RUBY_ID_SCOPE_MASK = (~(~0U<<(RUBY_ID_SCOPE_SHIFT-1))<<1)
};
enum ruby_method_ids {
idDot2 = 128,
idDot3 = 129,
idUPlus = 132,
idUMinus = 133,
idPow = 134,
idCmp = 135,
idPLUS = '+',
idMINUS = '-',
idMULT = '*',
idDIV = '/',
idMOD = '%',
idLTLT = 136,
idGTGT = 137,
idLT = '<',
idLE = 138,
idGT = '>',
idGE = 139,
idEq = 140,
idEqq = 141,
idNeq = 142,
idNot = '!',
idAnd = '&',
idOr = '|',
idBackquote = '`',
idEqTilde = 143,
idNeqTilde = 144,
idAREF = 145,
idASET = 146,
idCOLON2 = 147,
idANDOP = 148,
idOROP = 149,
idANDDOT = 150,
tPRESERVED_ID_BEGIN = 150,
idNilP,
idNULL,
idEmptyP,
idEqlP,
idRespond_to,
idRespond_to_missing,
idIFUNC,
idCFUNC,
id_core_set_method_alias,
id_core_set_variable_alias,
id_core_undef_method,
id_core_define_method,
id_core_define_singleton_method,
id_core_set_postexe,
id_core_hash_merge_ptr,
id_core_hash_merge_kwd,
id_core_raise,
id_core_sprintf,
id_debug_created_info,
tPRESERVED_ID_END,
tTOKEN_LOCAL_BEGIN = tPRESERVED_ID_END-1,
tMax,
tMin,
tFreeze,
tInspect,
tIntern,
tObject_id,
tConst_added,
tConst_missing,
tMethodMissing,
tMethod_added,
tSingleton_method_added,
tMethod_removed,
tSingleton_method_removed,
tMethod_undefined,
tSingleton_method_undefined,
tLength,
tSize,
tGets,
tSucc,
tEach,
tProc,
tLambda,
tSend,
t__send__,
t__attached__,
t__recursive_key__,
tInitialize,
tInitialize_copy,
tInitialize_clone,
tInitialize_dup,
tTo_int,
tTo_ary,
tTo_str,
tTo_sym,
tTo_hash,
tTo_proc,
tTo_io,
tTo_a,
tTo_s,
tTo_i,
tTo_f,
tTo_r,
tBt,
tBt_locations,
tCall,
tMesg,
tException,
tLocals,
tNOT,
tAND,
tOR,
tDiv,
tDivmod,
tFdiv,
tQuo,
tName,
tNil,
tPath,
tUScore,
tNUMPARAM_1,
tNUMPARAM_2,
tNUMPARAM_3,
tNUMPARAM_4,
tNUMPARAM_5,
tNUMPARAM_6,
tNUMPARAM_7,
tNUMPARAM_8,
tNUMPARAM_9,
tDefault,
tTOKEN_LOCAL_END,
tTOKEN_INSTANCE_BEGIN = tTOKEN_LOCAL_END-1,
tTOKEN_INSTANCE_END,
tTOKEN_GLOBAL_BEGIN = tTOKEN_INSTANCE_END-1,
tLASTLINE,
tBACKREF,
tERROR_INFO,
tTOKEN_GLOBAL_END,
tTOKEN_CONST_BEGIN = tTOKEN_GLOBAL_END-1,
tTOKEN_CONST_END,
tTOKEN_CLASS_BEGIN = tTOKEN_CONST_END-1,
tTOKEN_CLASS_END,
tTOKEN_ATTRSET_BEGIN = tTOKEN_CLASS_END-1,
tTOKEN_ATTRSET_END,
tNEXT_ID = tTOKEN_ATTRSET_END,
idMax = ((tMax<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMin = ((tMin<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idFreeze = ((tFreeze<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idInspect = ((tInspect<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idIntern = ((tIntern<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idObject_id = ((tObject_id<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idConst_added = ((tConst_added<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idConst_missing = ((tConst_missing<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMethodMissing = ((tMethodMissing<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMethod_added = ((tMethod_added<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSingleton_method_added = ((tSingleton_method_added<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMethod_removed = ((tMethod_removed<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSingleton_method_removed = ((tSingleton_method_removed<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMethod_undefined = ((tMethod_undefined<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSingleton_method_undefined = ((tSingleton_method_undefined<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idLength = ((tLength<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSize = ((tSize<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idGets = ((tGets<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSucc = ((tSucc<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idEach = ((tEach<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idProc = ((tProc<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idLambda = ((tLambda<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idSend = ((tSend<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
id__send__ = ((t__send__<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
id__attached__ = ((t__attached__<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
id__recursive_key__ = ((t__recursive_key__<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idInitialize = ((tInitialize<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idInitialize_copy = ((tInitialize_copy<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idInitialize_clone = ((tInitialize_clone<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idInitialize_dup = ((tInitialize_dup<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_int = ((tTo_int<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_ary = ((tTo_ary<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_str = ((tTo_str<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_sym = ((tTo_sym<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_hash = ((tTo_hash<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_proc = ((tTo_proc<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_io = ((tTo_io<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_a = ((tTo_a<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_s = ((tTo_s<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_i = ((tTo_i<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_f = ((tTo_f<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idTo_r = ((tTo_r<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idBt = ((tBt<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idBt_locations = ((tBt_locations<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idCall = ((tCall<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idMesg = ((tMesg<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idException = ((tException<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idLocals = ((tLocals<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNOT = ((tNOT<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idAND = ((tAND<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idOR = ((tOR<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idDiv = ((tDiv<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idDivmod = ((tDivmod<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idFdiv = ((tFdiv<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idQuo = ((tQuo<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idName = ((tName<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNil = ((tNil<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idPath = ((tPath<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idUScore = ((tUScore<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_1 = ((tNUMPARAM_1<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_2 = ((tNUMPARAM_2<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_3 = ((tNUMPARAM_3<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_4 = ((tNUMPARAM_4<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_5 = ((tNUMPARAM_5<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_6 = ((tNUMPARAM_6<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_7 = ((tNUMPARAM_7<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_8 = ((tNUMPARAM_8<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idNUMPARAM_9 = ((tNUMPARAM_9<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idDefault = ((tDefault<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_LOCAL|RUBY_ID_STATIC_SYM),
idLASTLINE = ((tLASTLINE<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_GLOBAL|RUBY_ID_STATIC_SYM),
idBACKREF = ((tBACKREF<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_GLOBAL|RUBY_ID_STATIC_SYM),
idERROR_INFO = ((tERROR_INFO<<RUBY_ID_SCOPE_SHIFT)|RUBY_ID_GLOBAL|RUBY_ID_STATIC_SYM),
tLAST_OP_ID = tPRESERVED_ID_END-1,
idLAST_OP_ID = tLAST_OP_ID >> RUBY_ID_SCOPE_SHIFT
};
void rb_obj_info_dump(VALUE obj);
void rb_obj_info_dump_loc(VALUE obj, const char *file, int line, const char *func);
void ruby_debug_breakpoint(void);
__attribute__((__format__(__printf__, (1), (2)))) void ruby_debug_printf(const char*, ...);
VALUE rb_ary_last(int, const VALUE *, VALUE);
void rb_ary_set_len(VALUE, long);
void rb_ary_delete_same(VALUE, VALUE);
VALUE rb_ary_hidden_new_fill(long capa);
VALUE rb_ary_at(VALUE, VALUE);
size_t rb_ary_memsize(VALUE);
VALUE rb_to_array_type(VALUE obj);
VALUE rb_to_array(VALUE obj);
void rb_ary_cancel_sharing(VALUE ary);
size_t rb_ary_size_as_embedded(VALUE ary);
void rb_ary_make_embedded(VALUE ary);
_Bool rb_ary_embeddable_p(VALUE ary);
VALUE rb_ary_diff(VALUE ary1, VALUE ary2);
static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
static inline _Bool ARY_PTR_USING_P(VALUE ary);
static inline void RARY_TRANSIENT_SET(VALUE ary);
static inline void RARY_TRANSIENT_UNSET(VALUE ary);
VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
VALUE rb_check_to_array(VALUE ary);
VALUE rb_ary_behead(VALUE, long);
VALUE rb_ary_aref1(VALUE ary, VALUE i);
struct rb_execution_context_struct;
VALUE rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
static inline VALUE
rb_ary_entry_internal(VALUE ary, long offset)
{
long len = rb_array_len(ary);
const VALUE *ptr = rb_array_const_ptr_transient(ary);
if (len == 0) return ((VALUE)RUBY_Qnil);
if (offset < 0) {
offset += len;
if (offset < 0) return ((VALUE)RUBY_Qnil);
}
else if (len <= offset) {
return ((VALUE)RUBY_Qnil);
}
return ptr[offset];
}
static inline _Bool
ARY_PTR_USING_P(VALUE ary)
{
return RB_FL_TEST_RAW(ary, ((VALUE)RUBY_FL_USER14));
}
__attribute__((__unused__))
static inline int
ary_should_not_be_shared_and_embedded(VALUE ary)
{
return !RB_FL_ALL_RAW(ary, RUBY_ELTS_SHARED|RARRAY_EMBED_FLAG);
}
static inline _Bool
ARY_SHARED_P(VALUE ary)
{
((void) (0));
((void) (0));
return RB_FL_TEST_RAW(ary, RUBY_ELTS_SHARED);
}
static inline _Bool
ARY_EMBED_P(VALUE ary)
{
((void) (0));
((void) (0));
return RB_FL_TEST_RAW(ary, RARRAY_EMBED_FLAG);
}
static inline VALUE
ARY_SHARED_ROOT(VALUE ary)
{
((void) (0));
return ((struct RArray *)(ary))->as.heap.aux.shared_root;
}
static inline _Bool
ARY_SHARED_ROOT_P(VALUE ary)
{
((void) (0));
return RB_FL_TEST_RAW(ary, ((VALUE)RUBY_FL_USER12));
}
static inline long
ARY_SHARED_ROOT_REFCNT(VALUE ary)
{
((void) (0));
return ((struct RArray *)(ary))->as.heap.aux.capa;
}
static inline void
RARY_TRANSIENT_SET(VALUE ary)
{
RB_FL_SET_RAW(ary, RARRAY_TRANSIENT_FLAG);
}
static inline void
RARY_TRANSIENT_UNSET(VALUE ary)
{
RB_FL_UNSET_RAW(ary, RARRAY_TRANSIENT_FLAG);
}
__attribute__((__pure__))
__attribute__((__artificial__))
static inline VALUE
RARRAY_AREF(VALUE ary, long i)
{
((void)0);
return rb_array_const_ptr_transient(ary)[i];
}
enum ruby_basic_operators {
BOP_PLUS,
BOP_MINUS,
BOP_MULT,
BOP_DIV,
BOP_MOD,
BOP_EQ,
BOP_EQQ,
BOP_LT,
BOP_LE,
BOP_LTLT,
BOP_AREF,
BOP_ASET,
BOP_LENGTH,
BOP_SIZE,
BOP_EMPTY_P,
BOP_NIL_P,
BOP_SUCC,
BOP_GT,
BOP_GE,
BOP_NOT,
BOP_NEQ,
BOP_MATCH,
BOP_FREEZE,
BOP_UMINUS,
BOP_MAX,
BOP_MIN,
BOP_CALL,
BOP_AND,
BOP_OR,
BOP_CMP,
BOP_DEFAULT,
BOP_LAST_
};
extern short ruby_vm_redefined_flag[BOP_LAST_];
typedef unsigned long long rb_serial_t;
struct rb_callable_method_entry_struct;
struct rb_method_definition_struct;
struct rb_execution_context_struct;
struct rb_control_frame_struct;
struct rb_callinfo;
enum method_missing_reason {
MISSING_NOENTRY = 0x00,
MISSING_PRIVATE = 0x01,
MISSING_PROTECTED = 0x02,
MISSING_FCALL = 0x04,
MISSING_VCALL = 0x08,
MISSING_SUPER = 0x10,
MISSING_MISSING = 0x20,
MISSING_NONE = 0x40
};static inline
VALUE rb_vm_push_frame_fname(struct rb_execution_context_struct *ec, VALUE fname);
VALUE rb_obj_is_thread(VALUE obj);
void rb_vm_mark(void *ptr);
void rb_vm_each_stack_value(void *ptr, void (*cb)(VALUE, void*), void *ctx);
__attribute__((__pure__)) VALUE rb_vm_top_self(void);
const void **rb_vm_get_insns_address_table(void);
VALUE rb_source_location(int *pline);
const char *rb_source_location_cstr(int *pline);
static void rb_vm_pop_cfunc_frame(void);
int rb_vm_add_root_module(VALUE module);
void rb_vm_check_redefinition_by_prepend(VALUE klass);
int rb_vm_check_optimizable_mid(VALUE mid);
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
static VALUE ruby_vm_special_exception_copy(VALUE);
__attribute__((__pure__)) st_table *rb_vm_fstring_table(void);
VALUE rb_vm_exec(struct rb_execution_context_struct *, _Bool);
VALUE rb_current_realfilepath(void);
VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE);
typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
rb_check_funcall_hook *hook, VALUE arg);
VALUE rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv,
rb_check_funcall_hook *hook, VALUE arg, int kw_splat);
const char *rb_type_str(enum ruby_value_type type);
VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE);
VALUE rb_check_funcall_basic_kw(VALUE, ID, VALUE, int, const VALUE*, int);
VALUE rb_yield_1(VALUE val);
VALUE rb_yield_force_blockarg(VALUE values);
VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
rb_block_call_func_t bl_proc, int min_argc, int max_argc,
VALUE data2);
void rb_check_stack_overflow(void);
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
struct rb_iseq_struct;
const struct rb_callcache *rb_vm_search_method_slowpath(const struct rb_callinfo *ci, VALUE klass);
struct rb_execution_context_struct;
int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv);
void rb_clear_constant_cache(void);
void rb_print_backtrace(void);
VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval);
VALUE rb_vm_backtrace(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_vm_backtrace_locations(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_make_backtrace(void);
void rb_backtrace_print_as_bugreport(void);
int rb_backtrace_p(VALUE obj);
VALUE rb_backtrace_to_str_ary(VALUE obj);
VALUE rb_backtrace_to_location_ary(VALUE obj);
void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
int rb_frame_info_p(VALUE obj);
int rb_get_node_id_from_frame_info(VALUE obj);
const struct rb_iseq_struct *rb_get_iseq_from_frame_info(VALUE obj);
VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec);
void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self);
struct rb_execution_context_struct;
struct rb_objspace;
typedef struct ractor_newobj_size_pool_cache {
struct RVALUE *freelist;
struct heap_page *using_page;
} rb_ractor_newobj_size_pool_cache_t;
typedef struct ractor_newobj_cache {
size_t incremental_mark_step_allocated_slots;
rb_ractor_newobj_size_pool_cache_t size_pool_caches[5];
} rb_ractor_newobj_cache_t;
extern VALUE *ruby_initial_gc_stress_ptr;
extern int ruby_disable_gc;
__attribute__((__malloc__)) void *ruby_mimmalloc(size_t size);
void ruby_mimfree(void *ptr);
void rb_objspace_set_event_hook(const rb_event_flag_t event);
VALUE rb_objspace_gc_enable(struct rb_objspace *);
VALUE rb_objspace_gc_disable(struct rb_objspace *);
void ruby_gc_set_params(void);
void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
__attribute__((__alloc_align__(1)))
__attribute__((__malloc__)) void *rb_aligned_malloc(size_t, size_t) __attribute__((__alloc_size__ (2)));
size_t rb_size_mul_or_raise(size_t, size_t, VALUE);
size_t rb_size_mul_add_or_raise(size_t, size_t, size_t, VALUE);
__attribute__((__malloc__)) void *rb_xmalloc_mul_add(size_t, size_t, size_t);
__attribute__((__malloc__)) void *rb_xcalloc_mul_add(size_t, size_t, size_t);
void *rb_xrealloc_mul_add(const void *, size_t, size_t, size_t);
__attribute__((__malloc__)) void *rb_xmalloc_mul_add_mul(size_t, size_t, size_t, size_t);
__attribute__((__malloc__)) void *rb_xcalloc_mul_add_mul(size_t, size_t, size_t, size_t);
static inline void *ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size) __attribute__((__returns_nonnull__)) __attribute__((__alloc_size__ (2)));
static inline void *ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count) __attribute__((__returns_nonnull__)) __attribute__((__alloc_size__ (2, 3)));
static inline void ruby_sized_xfree_inlined(void *ptr, size_t size);
VALUE rb_class_allocate_instance(VALUE klass);
void rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache);
size_t rb_gc_obj_slot_size(VALUE obj);
_Bool rb_gc_size_allocatable_p(size_t size);
int rb_objspace_garbage_object_p(VALUE obj);
const char *rb_objspace_data_type_name(VALUE obj);
VALUE rb_wb_protected_newobj_of(VALUE, VALUE, size_t);
VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE, size_t);
VALUE rb_ec_wb_protected_newobj_of(struct rb_execution_context_struct *ec, VALUE klass, VALUE flags, size_t);
size_t rb_obj_memsize_of(VALUE);
void rb_gc_verify_internal_consistency(void);
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
void rb_gc_mark_values(long n, const VALUE *values);
void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) __attribute__((__returns_nonnull__)) __attribute__((__alloc_size__ (2)));
void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) __attribute__((__returns_nonnull__)) __attribute__((__alloc_size__ (2, 3)));
void ruby_sized_xfree(void *x, size_t size);
int rb_ec_stack_check(struct rb_execution_context_struct *ec);
void rb_gc_writebarrier_remember(VALUE obj);
const char *rb_obj_info(VALUE obj);
static inline void *
ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size)
{
return ruby_xrealloc(ptr, new_size);
}
static inline void *
ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count)
{
return ruby_xrealloc2(ptr, new_count, elemsiz);
}
static inline void
ruby_sized_xfree_inlined(void *ptr, size_t size)
{
ruby_xfree(ptr);
}
enum imemo_type {
imemo_env = 0,
imemo_cref = 1,
imemo_svar = 2,
imemo_throw_data = 3,
imemo_ifunc = 4,
imemo_memo = 5,
imemo_ment = 6,
imemo_iseq = 7,
imemo_tmpbuf = 8,
imemo_ast = 9,
imemo_parser_strterm = 10,
imemo_callinfo = 11,
imemo_callcache = 12,
imemo_constcache = 13,
};
struct vm_svar {
VALUE flags;
const VALUE cref_or_me;
const VALUE lastline;
const VALUE backref;
const VALUE others;
};
struct vm_throw_data {
VALUE flags;
VALUE reserved;
const VALUE throw_obj;
const struct rb_control_frame_struct *catch_frame;
int throw_state;
};
struct vm_ifunc_argc {
int min, max;
};
struct vm_ifunc {
VALUE flags;
VALUE reserved;
rb_block_call_func_t func;
const void *data;
struct vm_ifunc_argc argc;
};
struct rb_imemo_tmpbuf_struct {
VALUE flags;
VALUE reserved;
VALUE *ptr;
struct rb_imemo_tmpbuf_struct *next;
size_t cnt;
};
struct MEMO {
VALUE flags;
VALUE reserved;
const VALUE v1;
const VALUE v2;
union {
long cnt;
long state;
const VALUE value;
void (*func)(void);
} u3;
};
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
void rb_strterm_mark(VALUE obj);
static inline enum imemo_type imemo_type(VALUE imemo);
static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
static inline _Bool imemo_throw_data_p(VALUE imemo);
static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
const char *rb_imemo_name(enum imemo_type type);
static inline enum imemo_type
imemo_type(VALUE imemo)
{
return (((struct RBasic *)(imemo))->flags >> ((VALUE)RUBY_FL_USHIFT)) & 0x0f;
}
static inline int
imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
{
if ((__builtin_expect(!!(!RB_SPECIAL_CONST_P(imemo)), 1))) {
const VALUE mask = (0x0f << ((VALUE)RUBY_FL_USHIFT)) | RUBY_T_MASK;
const VALUE expected_type = (imemo_type << ((VALUE)RUBY_FL_USHIFT)) | RUBY_T_IMEMO;
return expected_type == (((struct RBasic *)(imemo))->flags & mask);
}
else {
return 0;
}
}
static inline _Bool
imemo_throw_data_p(VALUE imemo)
{
return RB_TYPE_P(imemo, RUBY_T_IMEMO);
}
static inline struct vm_ifunc *
rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
{
return rb_vm_ifunc_new(func, data, 0, (-1));
}
static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer(void)
{
return rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0);
}
static inline void *
RB_IMEMO_TMPBUF_PTR(VALUE v)
{
const struct rb_imemo_tmpbuf_struct *p = (const void *)v;
return p->ptr;
}
static inline void *
rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
{
return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
}
static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
{
const void *src;
VALUE imemo;
rb_imemo_tmpbuf_t *tmpbuf;
void *dst;
size_t len;
rb_string_value(&(str));
imemo = rb_imemo_tmpbuf_auto_free_pointer();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
len = RSTRING_LEN(str);
src = RSTRING_PTR(str);
dst = ruby_xmalloc(len);
ruby_nonempty_memcpy(dst, src, len);
tmpbuf->ptr = dst;
return imemo;
}
static inline void
MEMO_V1_SET(struct MEMO *m, VALUE v)
{
rb_obj_write((VALUE)(m), ((VALUE *)(&m->v1)), (VALUE)(v), "./internal/imemo.h", 233);
}
static inline void
MEMO_V2_SET(struct MEMO *m, VALUE v)
{
rb_obj_write((VALUE)(m), ((VALUE *)(&m->v2)), (VALUE)(v), "./internal/imemo.h", 239);
}
typedef enum {
METHOD_VISI_UNDEF = 0x00,
METHOD_VISI_PUBLIC = 0x01,
METHOD_VISI_PRIVATE = 0x02,
METHOD_VISI_PROTECTED = 0x03,
METHOD_VISI_MASK = 0x03
} rb_method_visibility_t;
typedef struct rb_scope_visi_struct {
rb_method_visibility_t method_visi : 3;
unsigned int module_func : 1;
} rb_scope_visibility_t;
typedef struct rb_cref_struct {
VALUE flags;
VALUE refinements;
VALUE klass_or_self;
struct rb_cref_struct * next;
const rb_scope_visibility_t scope_visi;
} rb_cref_t;
typedef struct rb_method_entry_struct {
VALUE flags;
VALUE defined_class;
struct rb_method_definition_struct * const def;
ID called_id;
VALUE owner;
} rb_method_entry_t;
typedef struct rb_callable_method_entry_struct {
VALUE flags;
const VALUE defined_class;
struct rb_method_definition_struct * const def;
ID called_id;
const VALUE owner;
} rb_callable_method_entry_t;
static inline void
METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)
{
((void)0);
me->flags = (me->flags & ~(((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) | (visi << ((((VALUE)RUBY_FL_USHIFT) + 4)+0));
}
static inline void
METHOD_ENTRY_BASIC_SET(rb_method_entry_t *me, unsigned int basic)
{
((void)0);
me->flags = (me->flags & ~(((VALUE)RUBY_FL_USER6) )) | (basic << ((((VALUE)RUBY_FL_USHIFT) + 4)+2));
}
static inline void
METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsigned int basic)
{
((void)0);
((void)0);
me->flags =
(me->flags & ~(((VALUE)RUBY_FL_USER4)|((VALUE)RUBY_FL_USER5)|((VALUE)RUBY_FL_USER6))) |
((visi << ((((VALUE)RUBY_FL_USHIFT) + 4)+0)) | (basic << ((((VALUE)RUBY_FL_USHIFT) + 4)+2)));
}
static inline void
METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
{
dst->flags =
(dst->flags & ~(((VALUE)RUBY_FL_USER4)|((VALUE)RUBY_FL_USER5)|((VALUE)RUBY_FL_USER6)
|((VALUE)RUBY_FL_USER7))) |
(src->flags & (((VALUE)RUBY_FL_USER4)|((VALUE)RUBY_FL_USER5)|((VALUE)RUBY_FL_USER6)|((VALUE)RUBY_FL_USER7)));
}
typedef enum {
VM_METHOD_TYPE_ISEQ,
VM_METHOD_TYPE_CFUNC,
VM_METHOD_TYPE_ATTRSET,
VM_METHOD_TYPE_IVAR,
VM_METHOD_TYPE_BMETHOD,
VM_METHOD_TYPE_ZSUPER,
VM_METHOD_TYPE_ALIAS,
VM_METHOD_TYPE_UNDEF,
VM_METHOD_TYPE_NOTIMPLEMENTED,
VM_METHOD_TYPE_OPTIMIZED,
VM_METHOD_TYPE_MISSING,
VM_METHOD_TYPE_REFINED,
} rb_method_type_t;
__extension__ _Static_assert(VM_METHOD_TYPE_REFINED <= (1<<4), "VM_METHOD_TYPE_MINIMUM_BITS" ": " "VM_METHOD_TYPE_REFINED <= (1<<VM_METHOD_TYPE_MINIMUM_BITS)");
typedef struct rb_iseq_struct rb_iseq_t;
typedef struct rb_method_iseq_struct {
const rb_iseq_t * iseqptr;
rb_cref_t * cref;
} rb_method_iseq_t;
typedef struct rb_method_cfunc_struct {
VALUE (*func)();
VALUE (*invoker)(VALUE recv, int argc, const VALUE *argv, VALUE (*func)());
int argc;
} rb_method_cfunc_t;
typedef struct rb_method_attr_struct {
ID id;
VALUE location;
} rb_method_attr_t;
typedef struct rb_method_alias_struct {
struct rb_method_entry_struct * original_me;
} rb_method_alias_t;
typedef struct rb_method_refined_struct {
struct rb_method_entry_struct * orig_me;
VALUE owner;
} rb_method_refined_t;
typedef struct rb_method_bmethod_struct {
VALUE proc;
struct rb_hook_list_struct *hooks;
VALUE defined_ractor;
} rb_method_bmethod_t;
enum method_optimized_type {
OPTIMIZED_METHOD_TYPE_SEND,
OPTIMIZED_METHOD_TYPE_CALL,
OPTIMIZED_METHOD_TYPE_BLOCK_CALL,
OPTIMIZED_METHOD_TYPE_STRUCT_AREF,
OPTIMIZED_METHOD_TYPE_STRUCT_ASET,
OPTIMIZED_METHOD_TYPE__MAX
};
typedef struct rb_method_optimized {
enum method_optimized_type type;
unsigned int index;
} rb_method_optimized_t;
struct rb_method_definition_struct {
rb_method_type_t type : 4;
unsigned int iseq_overload: 1;
unsigned int no_redef_warning: 1;
unsigned int aliased : 1;
int reference_count : 28;
union {
rb_method_iseq_t iseq;
rb_method_cfunc_t cfunc;
rb_method_attr_t attr;
rb_method_alias_t alias;
rb_method_refined_t refined;
rb_method_bmethod_t bmethod;
rb_method_optimized_t optimized;
} body;
ID original_id;
uintptr_t method_serial;
};
struct rb_id_table;
typedef struct rb_method_definition_struct rb_method_definition_t;
__extension__ _Static_assert(__builtin_offsetof (rb_method_definition_t, body)==8, "sizeof_method_def" ": " "offsetof(rb_method_definition_t, body)==8");
void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(), int argc, rb_method_visibility_t visi);
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi);
void rb_add_method_optimized(VALUE klass, ID mid, enum method_optimized_type, unsigned int index, rb_method_visibility_t visi);
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex);
rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, rb_method_definition_t *def);
const rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
const rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
const rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
const rb_method_entry_t *rb_resolve_me_location(const rb_method_entry_t *, VALUE[5]);
const rb_callable_method_entry_t *rb_callable_method_entry(VALUE klass, ID id);
const rb_callable_method_entry_t *rb_callable_method_entry_or_negative(VALUE klass, ID id);
const rb_callable_method_entry_t *rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class);
const rb_callable_method_entry_t *rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class);
int rb_method_entry_arity(const rb_method_entry_t *me);
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
VALUE rb_method_entry_location(const rb_method_entry_t *me);
void rb_free_method_entry(const rb_method_entry_t *me);
const rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class);
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me);
void rb_scope_visibility_set(rb_method_visibility_t);
VALUE rb_unnamed_parameters(int arity);
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
void rb_clear_method_cache_all(void);
enum node_type {
NODE_SCOPE,
NODE_BLOCK,
NODE_IF,
NODE_UNLESS,
NODE_CASE,
NODE_CASE2,
NODE_CASE3,
NODE_WHEN,
NODE_IN,
NODE_WHILE,
NODE_UNTIL,
NODE_ITER,
NODE_FOR,
NODE_FOR_MASGN,
NODE_BREAK,
NODE_NEXT,
NODE_REDO,
NODE_RETRY,
NODE_BEGIN,
NODE_RESCUE,
NODE_RESBODY,
NODE_ENSURE,
NODE_AND,
NODE_OR,
NODE_MASGN,
NODE_LASGN,
NODE_DASGN,
NODE_GASGN,
NODE_IASGN,
NODE_CDECL,
NODE_CVASGN,
NODE_OP_ASGN1,
NODE_OP_ASGN2,
NODE_OP_ASGN_AND,
NODE_OP_ASGN_OR,
NODE_OP_CDECL,
NODE_CALL,
NODE_OPCALL,
NODE_FCALL,
NODE_VCALL,
NODE_QCALL,
NODE_SUPER,
NODE_ZSUPER,
NODE_LIST,
NODE_ZLIST,
NODE_VALUES,
NODE_HASH,
NODE_RETURN,
NODE_YIELD,
NODE_LVAR,
NODE_DVAR,
NODE_GVAR,
NODE_IVAR,
NODE_CONST,
NODE_CVAR,
NODE_NTH_REF,
NODE_BACK_REF,
NODE_MATCH,
NODE_MATCH2,
NODE_MATCH3,
NODE_LIT,
NODE_STR,
NODE_DSTR,
NODE_XSTR,
NODE_DXSTR,
NODE_EVSTR,
NODE_DREGX,
NODE_ONCE,
NODE_ARGS,
NODE_ARGS_AUX,
NODE_OPT_ARG,
NODE_KW_ARG,
NODE_POSTARG,
NODE_ARGSCAT,
NODE_ARGSPUSH,
NODE_SPLAT,
NODE_BLOCK_PASS,
NODE_DEFN,
NODE_DEFS,
NODE_ALIAS,
NODE_VALIAS,
NODE_UNDEF,
NODE_CLASS,
NODE_MODULE,
NODE_SCLASS,
NODE_COLON2,
NODE_COLON3,
NODE_DOT2,
NODE_DOT3,
NODE_FLIP2,
NODE_FLIP3,
NODE_SELF,
NODE_NIL,
NODE_TRUE,
NODE_FALSE,
NODE_ERRINFO,
NODE_DEFINED,
NODE_POSTEXE,
NODE_DSYM,
NODE_ATTRASGN,
NODE_LAMBDA,
NODE_ARYPTN,
NODE_HSHPTN,
NODE_FNDPTN,
NODE_ERROR,
NODE_LAST
};
typedef struct rb_code_position_struct {
int lineno;
int column;
} rb_code_position_t;
typedef struct rb_code_location_struct {
rb_code_position_t beg_pos;
rb_code_position_t end_pos;
} rb_code_location_t;
static inline rb_code_location_t
code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
{
rb_code_location_t loc;
loc.beg_pos = loc1->beg_pos;
loc.end_pos = loc2->end_pos;
return loc;
}
typedef struct rb_ast_id_table {
int size;
ID ids[];
} rb_ast_id_table_t;
typedef struct RNode {
VALUE flags;
union {
struct RNode *node;
ID id;
VALUE value;
rb_ast_id_table_t *tbl;
} u1;
union {
struct RNode *node;
ID id;
long argc;
VALUE value;
} u2;
union {
struct RNode *node;
ID id;
long state;
struct rb_args_info *args;
struct rb_ary_pattern_info *apinfo;
struct rb_fnd_pattern_info *fpinfo;
VALUE value;
} u3;
rb_code_location_t nd_loc;
int node_id;
} NODE;
VALUE rb_node_case_when_optimizable_literal(const NODE *const node);
typedef struct node_buffer_struct node_buffer_t;
typedef struct rb_ast_body_struct {
const NODE *root;
VALUE compile_option;
VALUE script_lines;
} rb_ast_body_t;
typedef struct rb_ast_struct {
VALUE flags;
node_buffer_t *node_buffer;
rb_ast_body_t body;
} rb_ast_t;
rb_ast_t *rb_ast_new(void);
void rb_ast_mark(rb_ast_t*);
void rb_ast_update_references(rb_ast_t*);
void rb_ast_dispose(rb_ast_t*);
void rb_ast_free(rb_ast_t*);
size_t rb_ast_memsize(const rb_ast_t*);
void rb_ast_add_mark_object(rb_ast_t*, VALUE);
void rb_ast_set_tokens(rb_ast_t*, VALUE);
VALUE rb_ast_tokens(rb_ast_t *ast);
NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
void rb_ast_delete_node(rb_ast_t*, NODE *n);
rb_ast_id_table_t *rb_ast_new_local_table(rb_ast_t*, int);
rb_ast_id_table_t *rb_ast_resize_latest_local_table(rb_ast_t*, int);
VALUE rb_parser_new(void);
VALUE rb_parser_end_seen_p(VALUE);
VALUE rb_parser_encoding(VALUE);
VALUE rb_parser_set_yydebug(VALUE, VALUE);
VALUE rb_parser_dump_tree(const NODE *node, int comment);
void rb_parser_set_options(VALUE, int, int, int, int);
rb_ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
rb_ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
rb_ast_t *rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int line);
void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
const char *ruby_node_name(int node);
const struct kwtable *rb_reserved_word(const char *, unsigned int);
struct rb_args_info {
NODE *pre_init;
NODE *post_init;
int pre_args_num;
int post_args_num;
ID first_post_arg;
ID rest_arg;
ID block_arg;
NODE *kw_args;
NODE *kw_rest_arg;
NODE *opt_args;
unsigned int no_kwarg: 1;
unsigned int ruby2_keywords: 1;
unsigned int forwarding: 1;
VALUE imemo;
};
struct rb_ary_pattern_info {
NODE *pre_args;
NODE *rest_arg;
NODE *post_args;
};
struct rb_fnd_pattern_info {
NODE *pre_rest_arg;
NODE *args;
NODE *post_rest_arg;
};
struct parser_params;
void *rb_parser_malloc(struct parser_params *, size_t);
void *rb_parser_realloc(struct parser_params *, void *, size_t);
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
void rb_parser_free(struct parser_params *, void *);
__attribute__((__format__(__printf__, (2), (3)))) void rb_parser_printf(struct parser_params *parser, const char *fmt, ...);
void rb_ast_node_type_change(NODE *n, enum node_type type);
static inline VALUE
rb_node_set_type(NODE *n, enum node_type t)
{
return (n)->flags=(((n)->flags&~(((VALUE)0x7f)<<8))|((((unsigned long)(t))<<8)&(((VALUE)0x7f)<<8)));
}
static inline _Bool
nd_type_p(const NODE *n, enum node_type t)
{
return (enum node_type)((int) (((n)->flags & (((VALUE)0x7f)<<8))>>8)) == t;
}
typedef unsigned int rb_atomic_t;
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline rb_atomic_t
rbimpl_atomic_fetch_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
return __atomic_fetch_add(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
__atomic_add_fetch(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_size_add(volatile size_t *ptr, size_t val)
{
__atomic_add_fetch(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_inc(volatile rb_atomic_t *ptr)
{
rbimpl_atomic_add(ptr, 1);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_size_inc(volatile size_t *ptr)
{
rbimpl_atomic_size_add(ptr, 1);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline rb_atomic_t
rbimpl_atomic_fetch_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
return __atomic_fetch_sub(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
__atomic_sub_fetch(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_size_sub(volatile size_t *ptr, size_t val)
{
__atomic_sub_fetch(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_dec(volatile rb_atomic_t *ptr)
{
rbimpl_atomic_sub(ptr, 1);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_size_dec(volatile size_t *ptr)
{
rbimpl_atomic_size_sub(ptr, 1);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_or(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
__atomic_or_fetch(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline rb_atomic_t
rbimpl_atomic_exchange(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
return __atomic_exchange_n(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline size_t
rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val)
{
return __atomic_exchange_n(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void *
rbimpl_atomic_ptr_exchange(void *volatile *ptr, const void *val)
{
__extension__ _Static_assert(sizeof *ptr == sizeof(size_t), "sizeof_voidp" ": " "sizeof *ptr == sizeof(size_t)");
const size_t sval = ((size_t)val);
volatile size_t *const sptr = ((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
return ((void *)sret);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline VALUE
rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
{
__extension__ _Static_assert(sizeof *ptr == sizeof(size_t), "sizeof_value" ": " "sizeof *ptr == sizeof(size_t)");
const size_t sval = ((size_t)val);
volatile size_t *const sptr = ((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
return ((VALUE)sret);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void
rbimpl_atomic_set(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
__atomic_store_n(ptr, val, 5);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline rb_atomic_t
rbimpl_atomic_cas(volatile rb_atomic_t *ptr, rb_atomic_t oldval, rb_atomic_t newval)
{
__atomic_compare_exchange_n(
ptr, &oldval, newval, 0, 5, 5);
return oldval;
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline size_t
rbimpl_atomic_size_cas(volatile size_t *ptr, size_t oldval, size_t newval)
{
__atomic_compare_exchange_n(
ptr, &oldval, newval, 0, 5, 5);
return oldval;
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline void *
rbimpl_atomic_ptr_cas(void **ptr, const void *oldval, const void *newval)
{
__extension__ _Static_assert(sizeof *ptr == sizeof(size_t), "sizeof_voidp" ": " "sizeof *ptr == sizeof(size_t)");
const size_t snew = ((size_t)newval);
const size_t sold = ((size_t)oldval);
volatile size_t *const sptr = ((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
return ((void *)sret);
}
__attribute__((__artificial__))
__attribute__((__nonnull__ (1)))
static inline VALUE
rbimpl_atomic_value_cas(volatile VALUE *ptr, VALUE oldval, VALUE newval)
{
__extension__ _Static_assert(sizeof *ptr == sizeof(size_t), "sizeof_value" ": " "sizeof *ptr == sizeof(size_t)");
const size_t snew = ((size_t)newval);
const size_t sold = ((size_t)oldval);
volatile size_t *const sptr = ((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
return ((VALUE)sret);
}
typedef uint32_t attr_index_t;
typedef uint32_t shape_id_t;
struct rb_shape {
struct rb_id_table * edges;
ID edge_name;
attr_index_t next_iv_index;
uint32_t capacity;
uint8_t type;
uint8_t size_pool_index;
shape_id_t parent_id;
};
typedef struct rb_shape rb_shape_t;
enum shape_type {
SHAPE_ROOT,
SHAPE_IVAR,
SHAPE_FROZEN,
SHAPE_CAPACITY_CHANGE,
SHAPE_INITIAL_CAPACITY,
SHAPE_T_OBJECT,
SHAPE_OBJ_TOO_COMPLEX,
};
static inline shape_id_t
RBASIC_SHAPE_ID(VALUE obj)
{
((void)0);
return (shape_id_t)((((uintptr_t)1 << 32) - 1) & ((((struct RBasic *)(obj))->flags) >> ((8 * 8) - 32)));
}
static inline void
RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
((struct RBasic *)(obj))->flags &= (((VALUE)-1) >> 32);
((struct RBasic *)(obj))->flags |= ((VALUE)(shape_id) << ((8 * 8) - 32));
}
static inline shape_id_t
ROBJECT_SHAPE_ID(VALUE obj)
{
((void)0);
return RBASIC_SHAPE_ID(obj);
}
static inline void
ROBJECT_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{
((void)0);
RBASIC_SET_SHAPE_ID(obj, shape_id);
}
static inline shape_id_t
RCLASS_SHAPE_ID(VALUE obj)
{
((void)0);
return RBASIC_SHAPE_ID(obj);
}
_Bool rb_shape_root_shape_p(rb_shape_t* shape);
rb_shape_t * rb_shape_get_root_shape(void);
uint8_t rb_shape_id_num_bits(void);
int32_t rb_shape_id_offset(void);
rb_shape_t* rb_shape_get_shape_by_id_without_assertion(shape_id_t shape_id);
rb_shape_t * rb_shape_get_parent(rb_shape_t * shape);
rb_shape_t* rb_shape_get_shape_by_id(shape_id_t shape_id);
shape_id_t rb_shape_get_shape_id(VALUE obj);
rb_shape_t * rb_shape_get_next_iv_shape(rb_shape_t * shape, ID id);
_Bool rb_shape_get_iv_index(rb_shape_t * shape, ID id, attr_index_t * value);
_Bool rb_shape_obj_too_complex(VALUE obj);
void rb_shape_set_shape(VALUE obj, rb_shape_t* shape);
rb_shape_t* rb_shape_get_shape(VALUE obj);
int rb_shape_frozen_shape_p(rb_shape_t* shape);
void rb_shape_transition_shape_frozen(VALUE obj);
void rb_shape_transition_shape_remove_ivar(VALUE obj, ID id, rb_shape_t *shape, VALUE * removed);
rb_shape_t * rb_shape_transition_shape_capa(rb_shape_t * shape, uint32_t new_capacity);
rb_shape_t* rb_shape_get_next(rb_shape_t* shape, VALUE obj, ID id);
rb_shape_t * rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape);
static inline uint32_t
ROBJECT_IV_CAPACITY(VALUE obj)
{
((void)0);
((void)0);
return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->capacity;
}
static inline st_table *
ROBJECT_IV_HASH(VALUE obj)
{
((void)0);
((void)0);
return (st_table *)((struct RObject *)(obj))->as.heap.ivptr;
}
static inline void
ROBJECT_SET_IV_HASH(VALUE obj, const struct rb_id_table *tbl)
{
((void)0);
((void)0);
((struct RObject *)(obj))->as.heap.ivptr = (VALUE *)tbl;
}
size_t rb_id_table_size(const struct rb_id_table *tbl);
static inline uint32_t
ROBJECT_IV_COUNT(VALUE obj)
{
if (ROBJECT_SHAPE_ID(obj) == ((5 * 2) + 1)) {
return (uint32_t)rb_st_table_size(ROBJECT_IV_HASH(obj));
}
else {
((void)0);
((void)0);
return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->next_iv_index;
}
}
static inline uint32_t
RBASIC_IV_COUNT(VALUE obj)
{
return rb_shape_get_shape_by_id(rb_shape_get_shape_id(obj))->next_iv_index;
}
static inline uint32_t
RCLASS_IV_COUNT(VALUE obj)
{
((void)0);
uint32_t ivc = rb_shape_get_shape_by_id(RCLASS_SHAPE_ID(obj))->next_iv_index;
return ivc;
}
rb_shape_t * rb_shape_alloc(ID edge_name, rb_shape_t * parent);
rb_shape_t * rb_shape_alloc_with_size_pool_index(ID edge_name, rb_shape_t * parent, uint8_t size_pool_index);
rb_shape_t * rb_shape_alloc_with_parent_id(ID edge_name, shape_id_t parent_id);
rb_shape_t *rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *orig_shape);
_Bool rb_shape_set_shape_id(VALUE obj, shape_id_t shape_id);
VALUE rb_obj_debug_shape(VALUE self, VALUE obj);
VALUE rb_shape_flags_mask(void);
void rb_shape_set_too_complex(VALUE obj);
typedef void each_shape_callback(rb_shape_t * shape, void *data);
void rb_shape_each_shape(each_shape_callback callback, void *data);
size_t rb_shape_memsize(rb_shape_t *shape);
size_t rb_shape_edges_count(rb_shape_t *shape);
size_t rb_shape_depth(rb_shape_t *shape);
shape_id_t rb_shape_id(rb_shape_t * shape);
struct sched_param
{
int sched_priority;
};
extern int clone (int (*__fn) (void *__arg), void *__child_stack,
int __flags, void *__arg, ...) __attribute__ ((__nothrow__ , __leaf__));
extern int unshare (int __flags) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_getcpu (void) __attribute__ ((__nothrow__ , __leaf__));
extern int setns (int __fd, int __nstype) __attribute__ ((__nothrow__ , __leaf__));
typedef unsigned long int __cpu_mask;
typedef struct
{
__cpu_mask __bits[1024 / (8 * sizeof (__cpu_mask))];
} cpu_set_t;
extern int __sched_cpucount (size_t __setsize, const cpu_set_t *__setp)
__attribute__ ((__nothrow__ , __leaf__));
extern cpu_set_t *__sched_cpualloc (size_t __count) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__));
extern void __sched_cpufree (cpu_set_t *__set) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_setparam (__pid_t __pid, const struct sched_param *__param)
__attribute__ ((__nothrow__ , __leaf__));
extern int sched_getparam (__pid_t __pid, struct sched_param *__param) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_setscheduler (__pid_t __pid, int __policy,
const struct sched_param *__param) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_getscheduler (__pid_t __pid) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_yield (void) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_get_priority_max (int __algorithm) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_get_priority_min (int __algorithm) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize,
const cpu_set_t *__cpuset) __attribute__ ((__nothrow__ , __leaf__));
extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize,
cpu_set_t *__cpuset) __attribute__ ((__nothrow__ , __leaf__));
enum
{
PTHREAD_CREATE_JOINABLE,
PTHREAD_CREATE_DETACHED
};
enum
{
PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_ADAPTIVE_NP
,
PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
, PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
};
enum
{
PTHREAD_MUTEX_STALLED,
PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED,
PTHREAD_MUTEX_ROBUST,
PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST
};
enum
{
PTHREAD_PRIO_NONE,
PTHREAD_PRIO_INHERIT,
PTHREAD_PRIO_PROTECT
};
enum
{
PTHREAD_RWLOCK_PREFER_READER_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
};
enum
{
PTHREAD_INHERIT_SCHED,
PTHREAD_EXPLICIT_SCHED
};
enum
{
PTHREAD_SCOPE_SYSTEM,
PTHREAD_SCOPE_PROCESS
};
enum
{
PTHREAD_PROCESS_PRIVATE,
PTHREAD_PROCESS_SHARED
};
struct _pthread_cleanup_buffer
{
void (*__routine) (void *);
void *__arg;
int __canceltype;
struct _pthread_cleanup_buffer *__prev;
};
enum
{
PTHREAD_CANCEL_ENABLE,
PTHREAD_CANCEL_DISABLE
};
enum
{
PTHREAD_CANCEL_DEFERRED,
PTHREAD_CANCEL_ASYNCHRONOUS
};
extern int pthread_create (pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),
void *__restrict __arg) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 3)));
extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));
extern int pthread_join (pthread_t __th, void **__thread_return);
extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
const struct timespec *__abstime);
extern int pthread_detach (pthread_t __th) __attribute__ ((__nothrow__ , __leaf__));
extern pthread_t pthread_self (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int pthread_equal (pthread_t __thread1, pthread_t __thread2)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern int pthread_attr_init (pthread_attr_t *__attr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_destroy (pthread_attr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
int *__detachstate)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
int __detachstate)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getguardsize (const pthread_attr_t *__attr,
size_t *__guardsize)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
size_t __guardsize)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr,
struct sched_param *__restrict __param)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
const struct sched_param *__restrict
__param) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict
__attr, int *__restrict __policy)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict
__attr, int *__restrict __inherit)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
int __inherit)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr,
int *__restrict __scope)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict
__attr, void **__restrict __stackaddr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2))) __attribute__ ((__deprecated__));
extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
void *__stackaddr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1))) __attribute__ ((__deprecated__));
extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict
__attr, size_t *__restrict __stacksize)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
size_t __stacksize)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr,
void **__restrict __stackaddr,
size_t *__restrict __stacksize)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2, 3)));
extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
size_t __stacksize) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
size_t __cpusetsize,
const cpu_set_t *__cpuset)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern int pthread_attr_getaffinity_np (const pthread_attr_t *__attr,
size_t __cpusetsize,
cpu_set_t *__cpuset)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern int pthread_getattr_default_np (pthread_attr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_setattr_default_np (const pthread_attr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
const struct sched_param *__param)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int pthread_getschedparam (pthread_t __target_thread,
int *__restrict __policy,
struct sched_param *__restrict __param)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2, 3)));
extern int pthread_setschedprio (pthread_t __target_thread, int __prio)
__attribute__ ((__nothrow__ , __leaf__));
extern int pthread_getname_np (pthread_t __target_thread, char *__buf,
size_t __buflen)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int pthread_setname_np (pthread_t __target_thread, const char *__name)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int pthread_getconcurrency (void) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_setconcurrency (int __level) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_yield (void) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,
const cpu_set_t *__cpuset)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
cpu_set_t *__cpuset)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (3)));
extern int pthread_once (pthread_once_t *__once_control,
void (*__init_routine) (void)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_setcancelstate (int __state, int *__oldstate);
extern int pthread_setcanceltype (int __type, int *__oldtype);
extern int pthread_cancel (pthread_t __th);
extern void pthread_testcancel (void);
typedef struct
{
struct
{
__jmp_buf __cancel_jmp_buf;
int __mask_was_saved;
} __cancel_jmp_buf[1];
void *__pad[4];
} __pthread_unwind_buf_t __attribute__ ((__aligned__));
struct __pthread_cleanup_frame
{
void (*__cancel_routine) (void *);
void *__cancel_arg;
int __do_it;
int __cancel_type;
};
extern __inline __attribute__ ((__gnu_inline__)) void
__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
{
if (__frame->__do_it)
__frame->__cancel_routine (__frame->__cancel_arg);
}
struct __jmp_buf_tag;
extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __attribute__ ((__nothrow__));
extern int pthread_mutex_init (pthread_mutex_t *__mutex,
const pthread_mutexattr_t *__mutexattr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
const struct timespec *__restrict
__abstime) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_getprioceiling (const pthread_mutex_t *
__restrict __mutex,
int *__restrict __prioceiling)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
int __prioceiling,
int *__restrict __old_ceiling)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 3)));
extern int pthread_mutex_consistent (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t *
__restrict __attr,
int *__restrict __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
int __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict
__attr, int *__restrict __kind)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *
__restrict __attr,
int *__restrict __protocol)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
int __protocol)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *
__restrict __attr,
int *__restrict __prioceiling)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
int __prioceiling)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
int *__robustness)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr,
int *__robustness)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
int __robustness)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
int __robustness)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
const pthread_rwlockattr_t *__restrict
__attr) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
const struct timespec *__restrict
__abstime) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
const struct timespec *__restrict
__abstime) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *
__restrict __attr,
int *__restrict __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
int __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *
__restrict __attr,
int *__restrict __pref)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
int __pref) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
const pthread_condattr_t *__restrict __cond_attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_cond_destroy (pthread_cond_t *__cond)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_cond_signal (pthread_cond_t *__cond)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_cond_broadcast (pthread_cond_t *__cond)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
pthread_mutex_t *__restrict __mutex)
__attribute__ ((__nonnull__ (1, 2)));
extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
pthread_mutex_t *__restrict __mutex,
const struct timespec *__restrict __abstime)
__attribute__ ((__nonnull__ (1, 2, 3)));
extern int pthread_condattr_init (pthread_condattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_condattr_getpshared (const pthread_condattr_t *
__restrict __attr,
int *__restrict __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
int __pshared) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_condattr_getclock (const pthread_condattr_t *
__restrict __attr,
__clockid_t *__restrict __clock_id)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
__clockid_t __clock_id)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_spin_lock (pthread_spinlock_t *__lock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
const pthread_barrierattr_t *__restrict
__attr, unsigned int __count)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
__attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *
__restrict __attr,
int *__restrict __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
int __pshared)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_key_create (pthread_key_t *__key,
void (*__destr_function) (void *))
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int pthread_key_delete (pthread_key_t __key) __attribute__ ((__nothrow__ , __leaf__));
extern void *pthread_getspecific (pthread_key_t __key) __attribute__ ((__nothrow__ , __leaf__));
extern int pthread_setspecific (pthread_key_t __key,
const void *__pointer) __attribute__ ((__nothrow__ , __leaf__)) ;
extern int pthread_getcpuclockid (pthread_t __thread_id,
__clockid_t *__clock_id)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (2)));
extern int pthread_atfork (void (*__prepare) (void),
void (*__parent) (void),
void (*__child) (void)) __attribute__ ((__nothrow__ , __leaf__));
extern __inline __attribute__ ((__gnu_inline__)) int
__attribute__ ((__nothrow__ , __leaf__)) pthread_equal (pthread_t __thread1, pthread_t __thread2)
{
return __thread1 == __thread2;
}
typedef pthread_t rb_nativethread_id_t;
typedef pthread_mutex_t rb_nativethread_lock_t;
typedef pthread_cond_t rb_nativethread_cond_t;
rb_nativethread_id_t rb_nativethread_self(void);
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock);
void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);
void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
int rb_native_mutex_trylock(rb_nativethread_lock_t *lock);
void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
void rb_native_cond_signal(rb_nativethread_cond_t *cond);
void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec);
void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
void *rb_allocate_sigaltstack(void);
void *rb_register_sigaltstack(void *);
struct rb_thread_sched_item {
union {
struct ccan_list_node ubf;
struct ccan_list_node readyq;
} node;
};
struct rb_native_thread {
int id;
rb_nativethread_id_t thread_id;
int tid;
struct rb_thread_struct *running_thread;
union
{
rb_nativethread_cond_t intr;
rb_nativethread_cond_t readyq;
} cond;
void *altstack;
};
struct rb_thread_sched {
const struct rb_thread_struct *running;
rb_nativethread_lock_t lock;
struct ccan_list_head readyq;
const struct rb_thread_struct *timer;
int timer_err;
rb_nativethread_cond_t switch_cond;
rb_nativethread_cond_t switch_wait_cond;
int need_yield;
int wait_yield;
};
extern _Thread_local struct rb_execution_context_struct *ruby_current_ec;
void rb_vm_encoded_insn_data_table_init(void);
typedef unsigned long rb_num_t;
typedef signed long rb_snum_t;
enum ruby_tag_type {
RUBY_TAG_NONE = 0x0,
RUBY_TAG_RETURN = 0x1,
RUBY_TAG_BREAK = 0x2,
RUBY_TAG_NEXT = 0x3,
RUBY_TAG_RETRY = 0x4,
RUBY_TAG_REDO = 0x5,
RUBY_TAG_RAISE = 0x6,
RUBY_TAG_THROW = 0x7,
RUBY_TAG_FATAL = 0x8,
RUBY_TAG_MASK = 0xf
};
enum ruby_vm_throw_flags {
VM_THROW_NO_ESCAPE_FLAG = 0x8000,
VM_THROW_STATE_MASK = 0xff
};
struct rb_thread_struct;
struct rb_control_frame_struct;
typedef struct rb_compile_option_struct rb_compile_option_t;
union ic_serial_entry {
rb_serial_t raw;
VALUE data[2];
};
struct iseq_inline_constant_cache_entry {
VALUE flags;
VALUE value;
VALUE _unused1;
VALUE _unused2;
const rb_cref_t *ic_cref;
};
__extension__ _Static_assert((__builtin_offsetof (struct iseq_inline_constant_cache_entry, ic_cref) + sizeof(const rb_cref_t *)) <= (sizeof(struct RBasic) + sizeof(VALUE[3])), "sizeof_iseq_inline_constant_cache_entry" ": " "(offsetof(struct iseq_inline_constant_cache_entry, ic_cref) + sizeof(const rb_cref_t *)) <= RVALUE_SIZE");
struct iseq_inline_constant_cache {
struct iseq_inline_constant_cache_entry *entry;
const ID *segments;
};
struct iseq_inline_iv_cache_entry {
uintptr_t value;
ID iv_set_name;
};
struct iseq_inline_cvar_cache_entry {
struct rb_cvar_class_tbl_entry *entry;
};
union iseq_inline_storage_entry {
struct {
struct rb_thread_struct *running_thread;
VALUE value;
} once;
struct iseq_inline_constant_cache ic_cache;
struct iseq_inline_iv_cache_entry iv_cache;
};
struct rb_calling_info {
const struct rb_callinfo *ci;
const struct rb_callcache *cc;
VALUE block_handler;
VALUE recv;
int argc;
int kw_splat;
};
struct rb_execution_context_struct;
typedef struct rb_iseq_location_struct {
VALUE pathobj;
VALUE base_label;
VALUE label;
int first_lineno;
int node_id;
rb_code_location_t code_location;
} rb_iseq_location_t;
static inline VALUE
pathobj_path(VALUE pathobj)
{
if (RB_TYPE_P(pathobj, RUBY_T_STRING)) {
return pathobj;
}
else {
((void)0);
return RARRAY_AREF(pathobj, 0);
}
}
static inline VALUE
pathobj_realpath(VALUE pathobj)
{
if (RB_TYPE_P(pathobj, RUBY_T_STRING)) {
return pathobj;
}
else {
((void)0);
return RARRAY_AREF(pathobj, 1);
}
}
struct rb_mjit_unit;
typedef uintptr_t iseq_bits_t;
enum rb_iseq_type {
ISEQ_TYPE_TOP,
ISEQ_TYPE_METHOD,
ISEQ_TYPE_BLOCK,
ISEQ_TYPE_CLASS,
ISEQ_TYPE_RESCUE,
ISEQ_TYPE_ENSURE,
ISEQ_TYPE_EVAL,
ISEQ_TYPE_MAIN,
ISEQ_TYPE_PLAIN
};
struct rb_iseq_constant_body {
enum rb_iseq_type type;
unsigned int iseq_size;
VALUE *iseq_encoded;
struct {
struct {
unsigned int has_lead : 1;
unsigned int has_opt : 1;
unsigned int has_rest : 1;
unsigned int has_post : 1;
unsigned int has_kw : 1;
unsigned int has_kwrest : 1;
unsigned int has_block : 1;
unsigned int ambiguous_param0 : 1;
unsigned int accepts_no_kwarg : 1;
unsigned int ruby2_keywords: 1;
} flags;
unsigned int size;
int lead_num;
int opt_num;
int rest_start;
int post_start;
int post_num;
int block_start;
const VALUE *opt_table;
const struct rb_iseq_param_keyword {
int num;
int required_num;
int bits_start;
int rest_start;
const ID *table;
VALUE *default_values;
} *keyword;
} param;
rb_iseq_location_t location;
struct iseq_insn_info {
const struct iseq_insn_info_entry *body;
unsigned int *positions;
unsigned int size;
struct succ_index_table *succ_index_table;
} insns_info;
const ID *local_table;
struct iseq_catch_table *catch_table;
const struct rb_iseq_struct *parent_iseq;
struct rb_iseq_struct *local_iseq;
union iseq_inline_storage_entry *is_entries;
struct rb_call_data *call_data;
struct {
rb_snum_t flip_count;
VALUE script_lines;
VALUE coverage;
VALUE pc2branchindex;
VALUE *original_iseq;
} variable;
unsigned int local_table_size;
unsigned int ic_size;
unsigned int ise_size;
unsigned int ivc_size;
unsigned int icvarc_size;
unsigned int ci_size;
unsigned int stack_max;
_Bool catch_except_p;
_Bool builtin_inline_p;
union {
iseq_bits_t * list;
iseq_bits_t single;
} mark_bits;
struct rb_id_table *outer_variables;
const rb_iseq_t *mandatory_only_iseq;
VALUE (*jit_func)(struct rb_execution_context_struct *, struct rb_control_frame_struct *);
long unsigned total_calls;
struct rb_mjit_unit *mjit_unit;
};
struct rb_iseq_struct {
VALUE flags;
VALUE wrapper;
struct rb_iseq_constant_body *body;
union {
struct iseq_compile_data *compile_data;
struct {
VALUE obj;
int index;
} loader;
struct {
struct rb_hook_list_struct *local_hooks;
rb_event_flag_t global_trace_events;
} exec;
} aux;
};
static inline const rb_iseq_t *
rb_iseq_check(const rb_iseq_t *iseq)
{
return iseq;
}
static inline const rb_iseq_t *
def_iseq_ptr(rb_method_definition_t *def)
{
return rb_iseq_check(def->body.iseq.iseqptr);
}
enum ruby_special_exceptions {
ruby_error_reenter,
ruby_error_nomemory,
ruby_error_sysstack,
ruby_error_stackfatal,
ruby_error_stream_closed,
ruby_special_error_count
};
struct rb_vm_struct;
typedef void rb_vm_at_exit_func(struct rb_vm_struct*);
typedef struct rb_at_exit_list {
rb_vm_at_exit_func *func;
struct rb_at_exit_list *next;
} rb_at_exit_list;
struct rb_objspace;
struct rb_objspace *rb_objspace_alloc(void);
void rb_objspace_free(struct rb_objspace *);
void rb_objspace_call_finalizer(struct rb_objspace *);
typedef struct rb_hook_list_struct {
struct rb_event_hook_struct *hooks;
rb_event_flag_t events;
unsigned int running;
_Bool need_clean;
_Bool is_local;
} rb_hook_list_t;
typedef const struct rb_builtin_function *RB_BUILTIN;
typedef struct rb_vm_struct {
VALUE self;
struct {
struct ccan_list_head set;
unsigned int cnt;
unsigned int blocking_cnt;
struct rb_ractor_struct *main_ractor;
struct rb_thread_struct *main_thread;
struct {
rb_nativethread_lock_t lock;
struct rb_ractor_struct *lock_owner;
unsigned int lock_rec;
_Bool barrier_waiting;
unsigned int barrier_cnt;
rb_nativethread_cond_t barrier_cond;
rb_nativethread_cond_t terminate_cond;
_Bool terminate_waiting;
} sync;
} ractor;
void *main_altstack;
rb_serial_t fork_gen;
rb_nativethread_lock_t waitpid_lock;
struct ccan_list_head waiting_pids;
struct ccan_list_head waiting_grps;
struct ccan_list_head waiting_fds;
volatile int ubf_async_safe;
unsigned int running: 1;
unsigned int thread_abort_on_exception: 1;
unsigned int thread_report_on_exception: 1;
unsigned int thread_ignore_deadlock: 1;
VALUE mark_object_ary;
const VALUE special_exceptions[ruby_special_error_count];
rb_shape_t *shape_list;
rb_shape_t *root_shape;
shape_id_t next_shape_id;
VALUE top_self;
VALUE load_path;
VALUE load_path_snapshot;
VALUE load_path_check_cache;
VALUE expanded_load_path;
VALUE loaded_features;
VALUE loaded_features_snapshot;
VALUE loaded_features_realpaths;
VALUE loaded_features_realpath_map;
struct st_table *loaded_features_index;
struct st_table *loading_table;
struct st_table *static_ext_inits;
struct {
VALUE cmd[(64 + 1)];
} trap_list;
struct st_table *ensure_rollback_table;
struct rb_postponed_job_struct *postponed_job_buffer;
rb_atomic_t postponed_job_index;
int src_encoding_index;
struct ccan_list_head workqueue;
rb_nativethread_lock_t workqueue_lock;
VALUE orig_progname, progname;
VALUE coverages, me2counter;
int coverage_mode;
st_table * defined_module_hash;
struct rb_objspace *objspace;
rb_at_exit_list *at_exit;
st_table *frozen_strings;
const struct rb_builtin_function *builtin_function_table;
int builtin_inline_index;
struct rb_id_table *negative_cme_table;
st_table *overloaded_cme_table;
struct rb_id_table *constant_cache;
ID inserting_constant_cache_id;
const struct rb_callcache *global_cc_cache_table[1023];
struct {
size_t thread_vm_stack_size;
size_t thread_machine_stack_size;
size_t fiber_vm_stack_size;
size_t fiber_machine_stack_size;
} default_params;
} rb_vm_t;
struct rb_captured_block {
VALUE self;
const VALUE *ep;
union {
const rb_iseq_t *iseq;
const struct vm_ifunc *ifunc;
VALUE val;
} code;
};
enum rb_block_handler_type {
block_handler_type_iseq,
block_handler_type_ifunc,
block_handler_type_symbol,
block_handler_type_proc
};
enum rb_block_type {
block_type_iseq,
block_type_ifunc,
block_type_symbol,
block_type_proc
};
struct rb_block {
union {
struct rb_captured_block captured;
VALUE symbol;
VALUE proc;
} as;
enum rb_block_type type;
};
typedef struct rb_control_frame_struct {
const VALUE *pc;
VALUE *sp;
const rb_iseq_t *iseq;
VALUE self;
const VALUE *ep;
const void *block_code;
VALUE *__bp__;
void *jit_return;
} rb_control_frame_t;
extern const rb_data_type_t ruby_threadptr_data_type;
static inline struct rb_thread_struct *
rb_thread_ptr(VALUE thval)
{
return (struct rb_thread_struct *)rb_check_typeddata(thval, &ruby_threadptr_data_type);
}
enum rb_thread_status {
THREAD_RUNNABLE,
THREAD_STOPPED,
THREAD_STOPPED_FOREVER,
THREAD_KILLED
};
typedef jmp_buf rb_jmpbuf_t;
struct rb_vm_tag {
VALUE tag;
VALUE retval;
rb_jmpbuf_t buf;
struct rb_vm_tag *prev;
enum ruby_tag_type state;
unsigned int lock_rec;
};
__extension__ _Static_assert(__builtin_offsetof (struct rb_vm_tag, buf) > 0, "rb_vm_tag_buf_offset" ": " "offsetof(struct rb_vm_tag, buf) > 0");
__extension__ _Static_assert(__builtin_offsetof (struct rb_vm_tag, buf) + sizeof(rb_jmpbuf_t) < sizeof(struct rb_vm_tag), "rb_vm_tag_buf_end" ": " "offsetof(struct rb_vm_tag, buf) + sizeof(rb_jmpbuf_t) < sizeof(struct rb_vm_tag)");
struct rb_unblock_callback {
rb_unblock_function_t *func;
void *arg;
};
struct rb_mutex_struct;
typedef struct rb_ensure_entry {
VALUE marker;
VALUE (*e_proc)(VALUE);
VALUE data2;
} rb_ensure_entry_t;
typedef struct rb_ensure_list {
struct rb_ensure_list *next;
struct rb_ensure_entry entry;
} rb_ensure_list_t;
typedef struct rb_fiber_struct rb_fiber_t;
struct rb_waiting_list {
struct rb_waiting_list *next;
struct rb_thread_struct *thread;
struct rb_fiber_struct *fiber;
};
struct rb_execution_context_struct {
VALUE *vm_stack;
size_t vm_stack_size;
rb_control_frame_t *cfp;
struct rb_vm_tag *tag;
rb_atomic_t interrupt_flag;
rb_atomic_t interrupt_mask;
rb_fiber_t *fiber_ptr;
struct rb_thread_struct *thread_ptr;
struct rb_id_table *local_storage;
VALUE local_storage_recursive_hash;
VALUE local_storage_recursive_hash_for_trace;
VALUE storage;
const VALUE *root_lep;
VALUE root_svar;
rb_ensure_list_t *ensure_list;
struct rb_trace_arg_struct *trace_arg;
VALUE errinfo;
VALUE passed_block_handler;
uint8_t raised_flag;
enum method_missing_reason method_missing_reason : 8;
VALUE private_const_reference;
struct {
VALUE *stack_start;
VALUE *stack_end;
size_t stack_maxsize;
__attribute__((__aligned__(8))) jmp_buf regs;
} machine;
};
typedef struct rb_execution_context_struct rb_execution_context_t;
void rb_ec_set_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size);
void rb_ec_initialize_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size);
void rb_ec_clear_vm_stack(rb_execution_context_t *ec);
struct rb_ext_config {
_Bool ractor_safe;
};
typedef struct rb_ractor_struct rb_ractor_t;
struct rb_native_thread;
typedef struct rb_thread_struct {
struct ccan_list_node lt_node;
VALUE self;
rb_ractor_t *ractor;
rb_vm_t *vm;
struct rb_native_thread *nt;
rb_execution_context_t *ec;
struct rb_thread_sched_item sched;
rb_atomic_t serial;
VALUE last_status;
struct rb_calling_info *calling;
VALUE top_self;
VALUE top_wrapper;
enum rb_thread_status status : 2;
unsigned int locking_native_thread : 1;
unsigned int to_kill : 1;
unsigned int abort_on_exception: 1;
unsigned int report_on_exception: 1;
unsigned int pending_interrupt_queue_checked: 1;
int8_t priority;
uint32_t running_time_us;
void *blocking_region_buffer;
VALUE thgroup;
VALUE value;
VALUE pending_interrupt_queue;
VALUE pending_interrupt_mask_stack;
rb_nativethread_lock_t interrupt_lock;
struct rb_unblock_callback unblock;
VALUE locking_mutex;
struct rb_mutex_struct *keeping_mutexes;
struct rb_waiting_list *join_list;
union {
struct {
VALUE proc;
VALUE args;
int kw_splat;
} proc;
struct {
VALUE (*func)(void *);
void *arg;
} func;
} invoke_arg;
enum thread_invoke_type {
thread_invoke_type_none = 0,
thread_invoke_type_proc,
thread_invoke_type_ractor_proc,
thread_invoke_type_func
} invoke_type;
VALUE stat_insn_usage;
rb_fiber_t *root_fiber;
VALUE scheduler;
unsigned int blocking;
VALUE name;
struct rb_ext_config ext_config;
} rb_thread_t;
static inline unsigned int
rb_th_serial(const rb_thread_t *th)
{
return (unsigned int)th->serial;
}
typedef enum {
VM_DEFINECLASS_TYPE_CLASS = 0x00,
VM_DEFINECLASS_TYPE_SINGLETON_CLASS = 0x01,
VM_DEFINECLASS_TYPE_MODULE = 0x02,
VM_DEFINECLASS_TYPE_MASK = 0x07
} rb_vm_defineclass_type_t;
rb_iseq_t *rb_iseq_new (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum rb_iseq_type);
rb_iseq_t *rb_iseq_new_top (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent);
rb_iseq_t *rb_iseq_new_main (const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt);
rb_iseq_t *rb_iseq_new_eval (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth);
rb_iseq_t *rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth,
enum rb_iseq_type, const rb_compile_option_t*);
struct iseq_link_anchor;
struct rb_iseq_new_with_callback_callback_func {
VALUE flags;
VALUE reserved;
void (*func)(rb_iseq_t *, struct iseq_link_anchor *, const void *);
const void *data;
};
static inline struct rb_iseq_new_with_callback_callback_func *
rb_iseq_new_with_callback_new_callback(
void (*func)(rb_iseq_t *, struct iseq_link_anchor *, const void *), const void *ptr)
{
VALUE memo = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)ptr, ((VALUE)RUBY_Qundef), ((VALUE)RUBY_Qfalse));
return (struct rb_iseq_new_with_callback_callback_func *)memo;
}
rb_iseq_t *rb_iseq_new_with_callback(const struct rb_iseq_new_with_callback_callback_func * ifunc,
VALUE name, VALUE path, VALUE realpath, int first_lineno,
const rb_iseq_t *parent, enum rb_iseq_type, const rb_compile_option_t*);
VALUE rb_iseq_disasm(const rb_iseq_t *iseq);
int rb_iseq_disasm_insn(VALUE str, const VALUE *iseqval, size_t pos, const rb_iseq_t *iseq, VALUE child);
attr_index_t rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq);
VALUE rb_iseq_coverage(const rb_iseq_t *iseq);
extern VALUE rb_cISeq;
extern VALUE rb_cRubyVM;
extern VALUE rb_mRubyVMFrozenCore;
extern VALUE rb_block_param_proxy;
typedef struct {
const struct rb_block block;
unsigned int is_from_method: 1;
unsigned int is_lambda: 1;
unsigned int is_isolated: 1;
} rb_proc_t;
VALUE rb_proc_isolate(VALUE self);
VALUE rb_proc_isolate_bang(VALUE self);
VALUE rb_proc_ractor_make_shareable(VALUE self);
typedef struct {
VALUE flags;
rb_iseq_t *iseq;
const VALUE *ep;
const VALUE *env;
unsigned int env_size;
} rb_env_t;
extern const rb_data_type_t ruby_binding_data_type;
typedef struct {
const struct rb_block block;
const VALUE pathobj;
int first_lineno;
} rb_binding_t;
enum vm_check_match_type {
VM_CHECKMATCH_TYPE_WHEN = 1,
VM_CHECKMATCH_TYPE_CASE = 2,
VM_CHECKMATCH_TYPE_RESCUE = 3
};
enum vm_special_object_type {
VM_SPECIAL_OBJECT_VMCORE = 1,
VM_SPECIAL_OBJECT_CBASE,
VM_SPECIAL_OBJECT_CONST_BASE
};
enum vm_svar_index {
VM_SVAR_LASTLINE = 0,
VM_SVAR_BACKREF = 1,
VM_SVAR_EXTRA_START = 2,
VM_SVAR_FLIPFLOP_START = 2
};
typedef struct iseq_inline_constant_cache *IC;
typedef struct iseq_inline_iv_cache_entry *IVC;
typedef struct iseq_inline_cvar_cache_entry *ICVARC;
typedef union iseq_inline_storage_entry *ISE;
typedef const struct rb_callinfo *CALL_INFO;
typedef const struct rb_callcache *CALL_CACHE;
typedef struct rb_call_data *CALL_DATA;
typedef VALUE CDHASH;
typedef rb_control_frame_t *
(*rb_insn_func_t)(rb_execution_context_t *, rb_control_frame_t *);
enum vm_frame_env_flags {
VM_FRAME_MAGIC_METHOD = 0x11110001,
VM_FRAME_MAGIC_BLOCK = 0x22220001,
VM_FRAME_MAGIC_CLASS = 0x33330001,
VM_FRAME_MAGIC_TOP = 0x44440001,
VM_FRAME_MAGIC_CFUNC = 0x55550001,
VM_FRAME_MAGIC_IFUNC = 0x66660001,
VM_FRAME_MAGIC_EVAL = 0x77770001,
VM_FRAME_MAGIC_RESCUE = 0x78880001,
VM_FRAME_MAGIC_DUMMY = 0x79990001,
VM_FRAME_MAGIC_MASK = 0x7fff0001,
VM_FRAME_FLAG_FINISH = 0x0020,
VM_FRAME_FLAG_BMETHOD = 0x0040,
VM_FRAME_FLAG_CFRAME = 0x0080,
VM_FRAME_FLAG_LAMBDA = 0x0100,
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200,
VM_FRAME_FLAG_CFRAME_KW = 0x0400,
VM_FRAME_FLAG_PASSED = 0x0800,
VM_ENV_FLAG_LOCAL = 0x0002,
VM_ENV_FLAG_ESCAPED = 0x0004,
VM_ENV_FLAG_WB_REQUIRED = 0x0008,
VM_ENV_FLAG_ISOLATED = 0x0010,
};
static inline void VM_FORCE_WRITE_SPECIAL_CONST(const VALUE *ptr, VALUE special_const_value);
static inline void
VM_ENV_FLAGS_SET(const VALUE *ep, VALUE flag)
{
VALUE flags = ep[( 0)];
((void)0);
VM_FORCE_WRITE_SPECIAL_CONST(&ep[( 0)], flags | flag);
}
static inline void
VM_ENV_FLAGS_UNSET(const VALUE *ep, VALUE flag)
{
VALUE flags = ep[( 0)];
((void)0);
VM_FORCE_WRITE_SPECIAL_CONST(&ep[( 0)], flags & ~flag);
}
static inline unsigned long
VM_ENV_FLAGS(const VALUE *ep, long flag)
{
VALUE flags = ep[( 0)];
((void)0);
return flags & flag;
}
static inline unsigned long
VM_FRAME_TYPE(const rb_control_frame_t *cfp)
{
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_MAGIC_MASK);
}
static inline int
VM_FRAME_LAMBDA_P(const rb_control_frame_t *cfp)
{
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_LAMBDA) != 0;
}
static inline int
VM_FRAME_CFRAME_KW_P(const rb_control_frame_t *cfp)
{
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_CFRAME_KW) != 0;
}
static inline int
VM_FRAME_FINISHED_P(const rb_control_frame_t *cfp)
{
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_FINISH) != 0;
}
static inline int
VM_FRAME_BMETHOD_P(const rb_control_frame_t *cfp)
{
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_BMETHOD) != 0;
}
static inline int
rb_obj_is_iseq(VALUE iseq)
{
return imemo_type_p(iseq, imemo_iseq);
}
static inline int
VM_FRAME_CFRAME_P(const rb_control_frame_t *cfp)
{
int cframe_p = VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_CFRAME) != 0;
((void)0);
return cframe_p;
}
static inline int
VM_FRAME_RUBYFRAME_P(const rb_control_frame_t *cfp)
{
return !VM_FRAME_CFRAME_P(cfp);
}
static inline int
VM_ENV_LOCAL_P(const VALUE *ep)
{
return VM_ENV_FLAGS(ep, VM_ENV_FLAG_LOCAL) ? 1 : 0;
}
static inline const VALUE *
VM_ENV_PREV_EP(const VALUE *ep)
{
((void)0);
return ((void *)(((ep[(-1)])) & ~0x03));
}
static inline VALUE
VM_ENV_BLOCK_HANDLER(const VALUE *ep)
{
((void)0);
return ep[(-1)];
}
static inline int
VM_ENV_ESCAPED_P(const VALUE *ep)
{
((void)0);
return VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) ? 1 : 0;
}
__attribute__((__nonnull__ (1)))
static inline VALUE
VM_ENV_ENVVAL(const VALUE *ep)
{
VALUE envval = ep[( 1)];
((void)0);
((void)0);
return envval;
}
__attribute__((__nonnull__ (1)))
static inline const rb_env_t *
VM_ENV_ENVVAL_PTR(const VALUE *ep)
{
return (const rb_env_t *)VM_ENV_ENVVAL(ep);
}
static inline const rb_env_t *
vm_env_new(VALUE *env_ep, VALUE *env_body, unsigned int env_size, const rb_iseq_t *iseq)
{
rb_env_t *env = (rb_env_t *)rb_imemo_new(imemo_env, (VALUE)env_ep, (VALUE)env_body, 0, (VALUE)iseq);
env->env_size = env_size;
env_ep[( 1)] = (VALUE)env;
return env;
}
static inline void
VM_FORCE_WRITE(const VALUE *ptr, VALUE v)
{
*((VALUE *)ptr) = v;
}
static inline void
VM_FORCE_WRITE_SPECIAL_CONST(const VALUE *ptr, VALUE special_const_value)
{
((void)0);
VM_FORCE_WRITE(ptr, special_const_value);
}
static inline void
VM_STACK_ENV_WRITE(const VALUE *ep, int index, VALUE v)
{
((void)0);
VM_FORCE_WRITE(&ep[index], v);
}static inline
const VALUE *rb_vm_ep_local_ep(const VALUE *ep);
const VALUE *rb_vm_proc_local_ep(VALUE proc);static inline
void rb_vm_block_ep_update(VALUE obj, const struct rb_block *dst, const VALUE *ep);
void rb_vm_block_copy(VALUE obj, const struct rb_block *dst, const struct rb_block *src);static inline
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp);
static inline const rb_control_frame_t *
RUBY_VM_END_CONTROL_FRAME(const rb_execution_context_t *ec)
{
return (rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size);
}
static inline int
RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
{
return !((void *)(RUBY_VM_END_CONTROL_FRAME(ec)) > (void *)(cfp));
}
static inline int
VM_BH_ISEQ_BLOCK_P(VALUE block_handler)
{
if ((block_handler & 0x03) == 0x01) {
return 1;
}
else {
return 0;
}
}
static inline VALUE
VM_BH_FROM_ISEQ_BLOCK(const struct rb_captured_block *captured)
{
VALUE block_handler = ((VALUE)(captured) | (0x01));
((void)0);
return block_handler;
}
static inline const struct rb_captured_block *
VM_BH_TO_ISEQ_BLOCK(VALUE block_handler)
{
struct rb_captured_block *captured = ((void *)((block_handler) & ~0x03));
((void)0);
return captured;
}
static inline int
VM_BH_IFUNC_P(VALUE block_handler)
{
if ((block_handler & 0x03) == 0x03) {
return 1;
}
else {
return 0;
}
}
static inline VALUE
VM_BH_FROM_IFUNC_BLOCK(const struct rb_captured_block *captured)
{
VALUE block_handler = ((VALUE)(captured) | (0x03));
((void)0);
return block_handler;
}
static inline const struct rb_captured_block *
VM_BH_TO_IFUNC_BLOCK(VALUE block_handler)
{
struct rb_captured_block *captured = ((void *)((block_handler) & ~0x03));
((void)0);
return captured;
}
static inline const struct rb_captured_block *
VM_BH_TO_CAPT_BLOCK(VALUE block_handler)
{
struct rb_captured_block *captured = ((void *)((block_handler) & ~0x03));
((void)0);
return captured;
}
static inline enum rb_block_handler_type
vm_block_handler_type(VALUE block_handler)
{
if (VM_BH_ISEQ_BLOCK_P(block_handler)) {
return block_handler_type_iseq;
}
else if (VM_BH_IFUNC_P(block_handler)) {
return block_handler_type_ifunc;
}
else if (RB_SYMBOL_P(block_handler)) {
return block_handler_type_symbol;
}
else {
((void)0);
return block_handler_type_proc;
}
}
static inline void
vm_block_handler_verify(__attribute__ ((__unused__)) VALUE block_handler)
{
((void)0);
}
static inline int
vm_cfp_forwarded_bh_p(const rb_control_frame_t *cfp, VALUE block_handler)
{
return ((VALUE) cfp->block_code) == block_handler;
}
static inline enum rb_block_type
vm_block_type(const struct rb_block *block)
{
return block->type;
}
static inline void
vm_block_type_set(const struct rb_block *block, enum rb_block_type type)
{
struct rb_block *mb = (struct rb_block *)block;
mb->type = type;
}
static inline const struct rb_block *
vm_proc_block(VALUE procval)
{
((void)0);
return &((rb_proc_t *)(((struct RTypedData *)(procval))->data))->block;
}
static inline const rb_iseq_t *vm_block_iseq(const struct rb_block *block);
static inline const VALUE *vm_block_ep(const struct rb_block *block);
static inline const rb_iseq_t *
vm_proc_iseq(VALUE procval)
{
return vm_block_iseq(vm_proc_block(procval));
}
static inline const VALUE *
vm_proc_ep(VALUE procval)
{
return vm_block_ep(vm_proc_block(procval));
}
static inline const rb_iseq_t *
vm_block_iseq(const struct rb_block *block)
{
switch (vm_block_type(block)) {
case block_type_iseq: return rb_iseq_check(block->as.captured.code.iseq);
case block_type_proc: return vm_proc_iseq(block->as.proc);
case block_type_ifunc:
case block_type_symbol: return ((void *)0);
}
__builtin_unreachable();
return ((void *)0);
}
static inline const VALUE *
vm_block_ep(const struct rb_block *block)
{
switch (vm_block_type(block)) {
case block_type_iseq:
case block_type_ifunc: return block->as.captured.ep;
case block_type_proc: return vm_proc_ep(block->as.proc);
case block_type_symbol: return ((void *)0);
}
__builtin_unreachable();
return ((void *)0);
}
static inline VALUE
vm_block_self(const struct rb_block *block)
{
switch (vm_block_type(block)) {
case block_type_iseq:
case block_type_ifunc:
return block->as.captured.self;
case block_type_proc:
return vm_block_self(vm_proc_block(block->as.proc));
case block_type_symbol:
return ((VALUE)RUBY_Qundef);
}
__builtin_unreachable();
return ((VALUE)RUBY_Qundef);
}
static inline VALUE
VM_BH_TO_SYMBOL(VALUE block_handler)
{
((void)0);
return block_handler;
}
static inline VALUE
VM_BH_FROM_SYMBOL(VALUE symbol)
{
((void)0);
return symbol;
}
static inline VALUE
VM_BH_TO_PROC(VALUE block_handler)
{
((void)0);
return block_handler;
}
static inline VALUE
VM_BH_FROM_PROC(VALUE procval)
{
((void)0);
return procval;
}
VALUE rb_thread_alloc(VALUE klass);
VALUE rb_binding_alloc(VALUE klass);
VALUE rb_proc_alloc(VALUE klass);
VALUE rb_proc_dup(VALUE self);
extern void rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp);
extern void rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc);
extern void rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp
);
void rb_vm_bugreport(const void *);
typedef void (*ruby_sighandler_t)(int);
__attribute__((__format__(__printf__, 4, 5)))
__attribute__((__noreturn__)) void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *, const char *fmt, ...);
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
VALUE rb_iseq_path(const rb_iseq_t *iseq);
VALUE rb_iseq_realpath(const rb_iseq_t *iseq);
VALUE rb_iseq_pathobj_new(VALUE path, VALUE realpath);
void rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath);
int rb_ec_frame_method_id_and_class(const rb_execution_context_t *ec, ID *idp, ID *called_idp, VALUE *klassp);
void rb_ec_setup_exception(const rb_execution_context_t *ec, VALUE mesg, VALUE cause);
VALUE rb_vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, int argc, const VALUE *argv, int kw_splat, VALUE block_handler);
VALUE rb_vm_make_proc_lambda(const rb_execution_context_t *ec, const struct rb_captured_block *captured, VALUE klass, int8_t is_lambda);
static inline VALUE
rb_vm_make_proc(const rb_execution_context_t *ec, const struct rb_captured_block *captured, VALUE klass)
{
return rb_vm_make_proc_lambda(ec, captured, klass, 0);
}
static inline VALUE
rb_vm_make_lambda(const rb_execution_context_t *ec, const struct rb_captured_block *captured, VALUE klass)
{
return rb_vm_make_proc_lambda(ec, captured, klass, 1);
}
VALUE rb_vm_make_binding(const rb_execution_context_t *ec, const rb_control_frame_t *src_cfp);
VALUE rb_vm_env_local_variables(const rb_env_t *env);
const rb_env_t *rb_vm_env_prev_env(const rb_env_t *env);
const VALUE *rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const ID *dynvars);
void rb_vm_inc_const_missing_count(void);
VALUE rb_vm_call_kw(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc,
const VALUE *argv, const rb_callable_method_entry_t *me, int kw_splat);static inline
void rb_vm_pop_frame_no_int(rb_execution_context_t *ec);
static void rb_vm_pop_frame(rb_execution_context_t *ec);
void rb_thread_start_timer_thread(void);
void rb_thread_stop_timer_thread(void);
void rb_thread_reset_timer_thread(void);
void rb_thread_wakeup_timer_thread(int);
static inline void
rb_vm_living_threads_init(rb_vm_t *vm)
{
ccan_list_head_init(&vm->waiting_fds);
ccan_list_head_init(&vm->waiting_pids);
ccan_list_head_init(&vm->workqueue);
ccan_list_head_init(&vm->waiting_grps);
ccan_list_head_init(&vm->ractor.set);
}
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp);
rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp);
int rb_vm_get_sourceline(const rb_control_frame_t *);
void rb_vm_stack_to_heap(rb_execution_context_t *ec);
void ruby_thread_init_stack(rb_thread_t *th);
rb_thread_t * ruby_thread_from_native(void);
int ruby_thread_set_native(rb_thread_t *th);
int rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *idp, ID *called_idp, VALUE *klassp);
void rb_vm_rewind_cfp(rb_execution_context_t *ec, rb_control_frame_t *cfp);
static VALUE rb_vm_bh_to_procval(const rb_execution_context_t *ec, VALUE block_handler);
void rb_vm_register_special_exception_str(enum ruby_special_exceptions sp, VALUE exception_class, VALUE mesg);
void rb_gc_mark_machine_stack(const rb_execution_context_t *ec);static inline
void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
static const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);
VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr);
rb_execution_context_t *rb_vm_main_ractor_ec(rb_vm_t *vm);
extern struct rb_ractor_struct *ruby_single_main_ractor;
extern rb_vm_t *ruby_current_vm_ptr;
extern rb_event_flag_t ruby_vm_event_flags;
extern rb_event_flag_t ruby_vm_event_enabled_global_flags;
extern unsigned int ruby_vm_event_local_num;
static inline rb_thread_t *
rb_ec_thread_ptr(const rb_execution_context_t *ec)
{
return ec->thread_ptr;
}
static inline rb_ractor_t *
rb_ec_ractor_ptr(const rb_execution_context_t *ec)
{
const rb_thread_t *th = rb_ec_thread_ptr(ec);
if (th) {
((void)0);
return th->ractor;
}
else {
return ((void *)0);
}
}
static inline rb_vm_t *
rb_ec_vm_ptr(const rb_execution_context_t *ec)
{
const rb_thread_t *th = rb_ec_thread_ptr(ec);
if (th) {
return th->vm;
}
else {
return ((void *)0);
}
}
static inline rb_execution_context_t *
rb_current_execution_context(_Bool expect_ec)
{
rb_execution_context_t *ec = ruby_current_ec;
((void)0);
return ec;
}
static inline rb_thread_t *
rb_current_thread(void)
{
const rb_execution_context_t *ec = rb_current_execution_context(1);
return rb_ec_thread_ptr(ec);
}
static inline rb_ractor_t *
rb_current_ractor(void)
{
if (ruby_single_main_ractor) {
return ruby_single_main_ractor;
}
else {
const rb_execution_context_t *ec = rb_current_execution_context(1);
return rb_ec_ractor_ptr(ec);
}
}
static inline rb_vm_t *
rb_current_vm(void)
{
return ruby_current_vm_ptr;
}
void rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec,
unsigned int recorded_lock_rec,
unsigned int current_lock_rec);
static inline unsigned int
rb_ec_vm_lock_rec(const rb_execution_context_t *ec)
{
rb_vm_t *vm = rb_ec_vm_ptr(ec);
if (vm->ractor.sync.lock_owner != rb_ec_ractor_ptr(ec)) {
return 0;
}
else {
return vm->ractor.sync.lock_rec;
}
}
enum {
TIMER_INTERRUPT_MASK = 0x01,
PENDING_INTERRUPT_MASK = 0x02,
POSTPONED_JOB_INTERRUPT_MASK = 0x04,
TRAP_INTERRUPT_MASK = 0x08,
TERMINATE_INTERRUPT_MASK = 0x10,
VM_BARRIER_INTERRUPT_MASK = 0x20,
};
static inline _Bool
RUBY_VM_INTERRUPTED_ANY(rb_execution_context_t *ec)
{
return ec->interrupt_flag & ~(ec)->interrupt_mask;
}
VALUE rb_exc_set_backtrace(VALUE exc, VALUE bt);
int rb_signal_buff_size(void);
int rb_signal_exec(rb_thread_t *th, int sig);
void rb_threadptr_check_signal(rb_thread_t *mth);
void rb_threadptr_signal_raise(rb_thread_t *th, int sig);
void rb_threadptr_signal_exit(rb_thread_t *th);
int rb_threadptr_execute_interrupts(rb_thread_t *, int);
void rb_threadptr_interrupt(rb_thread_t *th);
void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th);
void rb_threadptr_pending_interrupt_clear(rb_thread_t *th);
void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
VALUE rb_ec_get_errinfo(const rb_execution_context_t *ec);
void rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo);
void rb_execution_context_update(rb_execution_context_t *ec);
void rb_execution_context_mark(const rb_execution_context_t *ec);
void rb_fiber_close(rb_fiber_t *fib);
void Init_native_thread(rb_thread_t *th);
int rb_vm_check_ints_blocking(rb_execution_context_t *ec);
void rb_vm_cond_wait(rb_vm_t *vm, rb_nativethread_cond_t *cond);
void rb_vm_cond_timedwait(rb_vm_t *vm, rb_nativethread_cond_t *cond, unsigned long msec);
static inline void
rb_vm_check_ints(rb_execution_context_t *ec)
{
((void)0);
if ((__builtin_expect(!!(RUBY_VM_INTERRUPTED_ANY(ec)), 0))) {
rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);
}
}
struct rb_trace_arg_struct {
rb_event_flag_t event;
rb_execution_context_t *ec;
const rb_control_frame_t *cfp;
VALUE self;
ID id;
ID called_id;
VALUE klass;
VALUE data;
int klass_solved;
int lineno;
VALUE path;
};
void rb_hook_list_mark(rb_hook_list_t *hooks);
void rb_hook_list_free(rb_hook_list_t *hooks);
void rb_hook_list_connect_tracepoint(VALUE target, rb_hook_list_t *list, VALUE tpval, unsigned int target_line);
void rb_hook_list_remove_tracepoint(rb_hook_list_t *list, VALUE tpval);
void rb_exec_event_hooks(struct rb_trace_arg_struct *trace_arg, rb_hook_list_t *hooks, int pop_p);
static inline void
rb_exec_event_hook_orig(rb_execution_context_t *ec, rb_hook_list_t *hooks, rb_event_flag_t flag,
VALUE self, ID id, ID called_id, VALUE klass, VALUE data, int pop_p)
{
struct rb_trace_arg_struct trace_arg;
((void)0);
trace_arg.event = flag;
trace_arg.ec = ec;
trace_arg.cfp = ec->cfp;
trace_arg.self = self;
trace_arg.id = id;
trace_arg.called_id = called_id;
trace_arg.klass = klass;
trace_arg.data = data;
trace_arg.path = ((VALUE)RUBY_Qundef);
trace_arg.klass_solved = 0;
rb_exec_event_hooks(&trace_arg, hooks, pop_p);
}
struct rb_ractor_pub {
VALUE self;
uint32_t id;
rb_hook_list_t hooks;
};
static inline rb_hook_list_t *
rb_ec_ractor_hooks(const rb_execution_context_t *ec)
{
struct rb_ractor_pub *cr_pub = (struct rb_ractor_pub *)rb_ec_ractor_ptr(ec);
return &cr_pub->hooks;
}
static inline void
rb_exec_event_hook_script_compiled(rb_execution_context_t *ec, const rb_iseq_t *iseq, VALUE eval_script)
{
do { const rb_event_flag_t flag_arg_ = (0x2000); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, ec->cfp->self, 0, 0, 0, RB_NIL_P(eval_script) ? (VALUE)iseq : __extension__ ({ const VALUE args_to_new_ary[] = {eval_script, (VALUE)iseq}; if (__builtin_constant_p(2)) { __extension__ _Static_assert(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))) == (2), "rb_ary_new_from_args" ": " "numberof(args_to_new_ary) == (2)"); } rb_ary_new_from_values(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))), args_to_new_ary); }), 0); } } while (0);
}
void rb_vm_trap_exit(rb_vm_t *vm);
int rb_thread_check_trap_pending(void);
extern VALUE rb_get_coverages(void);
extern void rb_set_coverages(VALUE, int, VALUE);
extern void rb_clear_coverages(void);
extern void rb_reset_coverages(void);
extern void rb_resume_coverages(void);
extern void rb_suspend_coverages(void);
void rb_postponed_job_flush(rb_vm_t *vm);
extern VALUE rb_eRactorUnsafeError;
extern VALUE rb_eRactorIsolationError;
static inline void
vm_passed_block_handler_set(rb_execution_context_t *ec, VALUE block_handler)
{
vm_block_handler_verify(block_handler);
ec->passed_block_handler = block_handler;
}
static inline void
pass_passed_block_handler(rb_execution_context_t *ec)
{
VALUE block_handler = rb_vm_frame_block_handler(ec->cfp);
vm_passed_block_handler_set(ec, block_handler);
VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_PASSED);
}
extern int *__errno_location (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__const__));
extern char *program_invocation_name;
extern char *program_invocation_short_name;
typedef int error_t;
static inline void
rb_ec_vm_lock_rec_check(const rb_execution_context_t *ec, unsigned int recorded_lock_rec)
{
unsigned int current_lock_rec = rb_ec_vm_lock_rec(ec);
if (current_lock_rec != recorded_lock_rec) {
rb_ec_vm_lock_rec_release(ec, recorded_lock_rec, current_lock_rec);
}
}
static inline int
rb_ec_tag_state(const rb_execution_context_t *ec)
{
struct rb_vm_tag *tag = ec->tag;
enum ruby_tag_type state = tag->state;
tag->state = RUBY_TAG_NONE;
rb_ec_vm_lock_rec_check(ec, tag->lock_rec);
return state;
}
__attribute__((__noreturn__)) static inline void rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st);
static inline void
rb_ec_tag_jump(const rb_execution_context_t *ec, enum ruby_tag_type st)
{
ec->tag->state = st;
_longjmp(((ec->tag->buf)),(1));
}
static inline int CREF_SINGLETON(const rb_cref_t *cref);
static inline VALUE
CREF_CLASS(const rb_cref_t *cref)
{
if (CREF_SINGLETON(cref)) {
return rb_class_of(cref->klass_or_self);
}
else {
return cref->klass_or_self;
}
}
static inline VALUE
CREF_CLASS_FOR_DEFINITION(const rb_cref_t *cref)
{
if (CREF_SINGLETON(cref)) {
return rb_singleton_class(cref->klass_or_self);
}
else {
return cref->klass_or_self;
}
}
static inline rb_cref_t *
CREF_NEXT(const rb_cref_t *cref)
{
return cref->next;
}
static inline const rb_scope_visibility_t *
CREF_SCOPE_VISI(const rb_cref_t *cref)
{
return &cref->scope_visi;
}
static inline VALUE
CREF_REFINEMENTS(const rb_cref_t *cref)
{
return cref->refinements;
}
static inline void
CREF_REFINEMENTS_SET(rb_cref_t *cref, VALUE refs)
{
rb_obj_write((VALUE)(cref), ((VALUE *)(&cref->refinements)), (VALUE)(refs), "./eval_intern.h", 227);
}
static inline int
CREF_PUSHED_BY_EVAL(const rb_cref_t *cref)
{
return cref->flags & ((VALUE)RUBY_FL_USER5);
}
static inline void
CREF_PUSHED_BY_EVAL_SET(rb_cref_t *cref)
{
cref->flags |= ((VALUE)RUBY_FL_USER5);
}
static inline int
CREF_SINGLETON(const rb_cref_t *cref)
{
return cref->flags & ((VALUE)RUBY_FL_USER7);
}
static inline void
CREF_SINGLETON_SET(rb_cref_t *cref)
{
cref->flags |= ((VALUE)RUBY_FL_USER7);
}
static inline int
CREF_OMOD_SHARED(const rb_cref_t *cref)
{
return cref->flags & ((VALUE)RUBY_FL_USER6);
}
static inline void
CREF_OMOD_SHARED_SET(rb_cref_t *cref)
{
cref->flags |= ((VALUE)RUBY_FL_USER6);
}
static inline void
CREF_OMOD_SHARED_UNSET(rb_cref_t *cref)
{
cref->flags &= ~((VALUE)RUBY_FL_USER6);
}
enum {
RAISED_EXCEPTION = 1,
RAISED_STACKOVERFLOW = 2,
RAISED_NOMEMORY = 4
};
int rb_ec_set_raised(rb_execution_context_t *ec);
int rb_ec_reset_raised(rb_execution_context_t *ec);
int rb_ec_stack_check(rb_execution_context_t *ec);
VALUE rb_f_eval(int argc, const VALUE *argv, VALUE self);
VALUE rb_make_exception(int argc, const VALUE *argv);
__attribute__((__noreturn__)) void rb_method_name_error(VALUE, VALUE);
__attribute__((__noreturn__)) void rb_fiber_start(rb_fiber_t*);
__attribute__((__noreturn__)) void rb_print_undef(VALUE, ID, rb_method_visibility_t);
__attribute__((__noreturn__)) void rb_print_undef_str(VALUE, VALUE);
__attribute__((__noreturn__)) void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t);
__attribute__((__noreturn__)) void rb_vm_localjump_error(const char *,VALUE, int);
__attribute__((__noreturn__)) void rb_vm_jump_tag_but_local_jump(int);
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
rb_cref_t *rb_vm_cref(void);
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
void rb_vm_set_progname(VALUE filename);
VALUE rb_vm_cbase(void);
VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec);
VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n);
VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, _Bool skip_internal);
static inline char *
rb_char_next(const char *p)
{
if (p) {
int len = mblen(p, 0x7fffffff);
p += len > 0 ? len : 1;
}
return (char *)p;
}
const char *rb_obj_info(VALUE obj);
const char *rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj);
struct rb_thread_struct;
size_t rb_size_pool_slot_size(unsigned char pool_id);
size_t rb_objspace_data_type_memsize(VALUE obj);
void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
int rb_objspace_markable_object_p(VALUE obj);
int rb_objspace_internal_object_p(VALUE obj);
int rb_objspace_marked_object_p(VALUE obj);
void rb_objspace_each_objects(
int (*callback)(void *start, void *end, size_t stride, void *data),
void *data);
void rb_objspace_each_objects_without_setup(
int (*callback)(void *, void *, size_t, void *),
void *data);
size_t rb_gc_obj_slot_size(VALUE obj);
VALUE rb_gc_disable_no_rest(void);
struct rb_iseq_struct;
int rb_dvar_defined(ID, const struct rb_iseq_struct *);
int rb_local_defined(ID, const struct rb_iseq_struct *);
const char *rb_insns_name(int i);
VALUE rb_insns_name_array(void);
int rb_iseq_cdhash_cmp(VALUE val, VALUE lit);
st_index_t rb_iseq_cdhash_hash(VALUE a);
int rb_vm_insn_addr2insn(const void *);
int rb_vm_insn_decode(const VALUE encoded);
extern _Bool ruby_vm_keep_script_lines;
rb_event_flag_t rb_iseq_event_flags(const struct rb_iseq_struct *iseq, size_t pos);
extern const int ruby_api_version[];
typedef void (*rb_iseq_callback)(const rb_iseq_t *, void *);
extern const ID rb_iseq_shared_exc_local_tbl[];
static inline rb_snum_t
ISEQ_FLIP_CNT_INCREMENT(const rb_iseq_t *iseq)
{
rb_snum_t cnt = ((iseq)->body)->variable.flip_count;
((iseq)->body)->variable.flip_count += 1;
return cnt;
}
static inline VALUE *
ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
{
return ((iseq)->body)->variable.original_iseq;
}
static inline void
ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq)
{
void *ptr = ((iseq)->body)->variable.original_iseq;
((iseq)->body)->variable.original_iseq = ((void *)0);
if (ptr) {
ruby_xfree(ptr);
}
}
static inline VALUE *
ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
{
return ((iseq)->body)->variable.original_iseq =
((VALUE *)ruby_xmalloc2((size), sizeof(VALUE)));
}
struct iseq_compile_data {
const VALUE err_info;
const VALUE catch_table_ary;
struct iseq_label_data *start_label;
struct iseq_label_data *end_label;
struct iseq_label_data *redo_label;
const rb_iseq_t *current_block;
struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
struct {
struct iseq_compile_data_storage *storage_head;
struct iseq_compile_data_storage *storage_current;
} node;
struct {
struct iseq_compile_data_storage *storage_head;
struct iseq_compile_data_storage *storage_current;
} insn;
_Bool in_rescue;
_Bool in_masgn;
int loopval_popped;
int last_line;
int label_no;
int node_level;
int isolated_depth;
unsigned int ci_index;
unsigned int ic_index;
const rb_compile_option_t *option;
struct rb_id_table *ivar_cache_table;
const struct rb_builtin_function *builtin_function_table;
const NODE *root_node;
};
static inline struct iseq_compile_data *
ISEQ_COMPILE_DATA(const rb_iseq_t *iseq)
{
if (iseq->flags & ((VALUE)RUBY_FL_USER6)) {
return iseq->aux.compile_data;
}
else {
return ((void *)0);
}
}
static inline void
ISEQ_COMPILE_DATA_ALLOC(rb_iseq_t *iseq)
{
iseq->aux.compile_data = (((struct iseq_compile_data *)ruby_xcalloc((1), sizeof(struct iseq_compile_data))));
iseq->flags |= ((VALUE)RUBY_FL_USER6);
}
static inline void
ISEQ_COMPILE_DATA_CLEAR(rb_iseq_t *iseq)
{
iseq->flags &= ~((VALUE)RUBY_FL_USER6);
iseq->aux.compile_data = ((void *)0);
}
static inline rb_iseq_t *
iseq_imemo_alloc(void)
{
return (rb_iseq_t *)rb_imemo_new(imemo_iseq, 0, 0, 0, 0);
}
VALUE rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt);
void rb_ibf_load_iseq_complete(rb_iseq_t *iseq);
const rb_iseq_t *rb_iseq_ibf_load(VALUE str);
const rb_iseq_t *rb_iseq_ibf_load_bytes(const char *cstr, size_t);
VALUE rb_iseq_ibf_load_extra_data(VALUE str);
void rb_iseq_init_trace(rb_iseq_t *iseq);
int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line, _Bool target_bmethod);
int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);
int rb_vm_insn_addr2opcode(const void *addr);
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node);
VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc);
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
VALUE locals, VALUE args,
VALUE exception, VALUE body);
void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *arena);
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
int rb_iseq_node_id(const rb_iseq_t *iseq, size_t pos);
void rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events);
void rb_iseq_trace_set_all(rb_event_flag_t turnon_events);
void rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq);
struct rb_iseq_constant_body *rb_iseq_constant_body_alloc(void);
VALUE rb_iseqw_new(const rb_iseq_t *iseq);
const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq);
int rb_iseq_from_eval_p(const rb_iseq_t *iseq);
VALUE rb_iseq_type(const rb_iseq_t *iseq);
VALUE rb_iseq_label(const rb_iseq_t *iseq);
VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
void rb_iseq_code_location(const rb_iseq_t *iseq, int *first_lineno, int *first_column, int *last_lineno, int *last_column);
void rb_iseq_remove_coverage_all(void);
const rb_iseq_t *rb_method_iseq(VALUE body);
const rb_iseq_t *rb_proc_get_iseq(VALUE proc, int *is_proc);
struct rb_compile_option_struct {
unsigned int inline_const_cache: 1;
unsigned int peephole_optimization: 1;
unsigned int tailcall_optimization: 1;
unsigned int specialized_instruction: 1;
unsigned int operands_unification: 1;
unsigned int instructions_unification: 1;
unsigned int stack_caching: 1;
unsigned int frozen_string_literal: 1;
unsigned int debug_frozen_string_literal: 1;
unsigned int coverage_enabled: 1;
int debug_level;
};
struct iseq_insn_info_entry {
int line_no;
int node_id;
rb_event_flag_t events;
};
enum rb_catch_type {
CATCH_TYPE_RESCUE = __builtin_choose_expr( __builtin_constant_p(1), ((VALUE)(1)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(1)),
CATCH_TYPE_ENSURE = __builtin_choose_expr( __builtin_constant_p(2), ((VALUE)(2)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(2)),
CATCH_TYPE_RETRY = __builtin_choose_expr( __builtin_constant_p(3), ((VALUE)(3)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(3)),
CATCH_TYPE_BREAK = __builtin_choose_expr( __builtin_constant_p(4), ((VALUE)(4)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(4)),
CATCH_TYPE_REDO = __builtin_choose_expr( __builtin_constant_p(5), ((VALUE)(5)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(5)),
CATCH_TYPE_NEXT = __builtin_choose_expr( __builtin_constant_p(6), ((VALUE)(6)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(6))
};
struct iseq_catch_table_entry {
enum rb_catch_type type;
rb_iseq_t *iseq;
unsigned int start;
unsigned int end;
unsigned int cont;
unsigned int sp;
};
struct iseq_catch_table { unsigned int size; struct iseq_catch_table_entry entries[]; } __attribute__((packed));
static inline int
iseq_catch_table_bytes(int n)
{
enum {
catch_table_entry_size = sizeof(struct iseq_catch_table_entry),
catch_table_entries_max = (0x7fffffff - __builtin_offsetof (struct iseq_catch_table, entries)) / catch_table_entry_size
};
if (n > catch_table_entries_max) rb_fatal("too large iseq_catch_table - %d", n);
return (int)(__builtin_offsetof (struct iseq_catch_table, entries) +
n * catch_table_entry_size);
}
struct iseq_compile_data_storage {
struct iseq_compile_data_storage *next;
unsigned int pos;
unsigned int size;
char buff[];
};
enum defined_type {
DEFINED_NOT_DEFINED,
DEFINED_NIL = 1,
DEFINED_IVAR,
DEFINED_LVAR,
DEFINED_GVAR,
DEFINED_CVAR,
DEFINED_CONST,
DEFINED_METHOD,
DEFINED_YIELD,
DEFINED_ZSUPER,
DEFINED_SELF,
DEFINED_TRUE,
DEFINED_FALSE,
DEFINED_ASGN,
DEFINED_EXPR,
DEFINED_REF,
DEFINED_FUNC,
DEFINED_CONST_FROM
};
VALUE rb_iseq_defined_string(enum defined_type type);
VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
struct rb_thread_struct;
struct rb_fiber_struct;
struct rb_execution_context_struct;
void rb_fiber_reset_root_local_storage(struct rb_thread_struct *);
void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(VALUE), VALUE (*rollback_func)(VALUE));
void rb_jit_cont_init(void);
void rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data);
void rb_jit_cont_finish(void);
VALUE rb_fiber_inherit_storage(struct rb_execution_context_struct *ec, struct rb_fiber_struct *fiber);
VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber);
unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber);
struct rb_execution_context_struct * rb_fiberptr_get_ec(struct rb_fiber_struct *fiber);
enum ruby_coderange_type {
RUBY_ENC_CODERANGE_UNKNOWN = 0,
RUBY_ENC_CODERANGE_7BIT = ((int)RUBY_FL_USER8),
RUBY_ENC_CODERANGE_VALID = ((int)RUBY_FL_USER9),
RUBY_ENC_CODERANGE_BROKEN = ((int)(RUBY_FL_USER8|RUBY_FL_USER9)),
RUBY_ENC_CODERANGE_MASK = (RUBY_ENC_CODERANGE_7BIT|
RUBY_ENC_CODERANGE_VALID|
RUBY_ENC_CODERANGE_BROKEN)
};
__attribute__((__const__))
static inline int
rb_enc_coderange_clean_p(int cr)
{
return (cr ^ (cr >> 1)) & RUBY_ENC_CODERANGE_7BIT;
}
__attribute__((__const__))
static inline _Bool
RB_ENC_CODERANGE_CLEAN_P(enum ruby_coderange_type cr)
{
return rb_enc_coderange_clean_p(cr);
}
__attribute__((__pure__))
static inline enum ruby_coderange_type
RB_ENC_CODERANGE(VALUE obj)
{
VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENC_CODERANGE_MASK);
return ((enum ruby_coderange_type)ret);
}
__attribute__((__pure__))
static inline _Bool
RB_ENC_CODERANGE_ASCIIONLY(VALUE obj)
{
return RB_ENC_CODERANGE(obj) == RUBY_ENC_CODERANGE_7BIT;
}
static inline void
RB_ENC_CODERANGE_SET(VALUE obj, enum ruby_coderange_type cr)
{
RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
RB_FL_SET_RAW(obj, cr);
}
static inline void
RB_ENC_CODERANGE_CLEAR(VALUE obj)
{
RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
}
__attribute__((__const__))
static inline enum ruby_coderange_type
RB_ENC_CODERANGE_AND(enum ruby_coderange_type a, enum ruby_coderange_type b)
{
if (a == RUBY_ENC_CODERANGE_7BIT) {
return b;
}
else if (a != RUBY_ENC_CODERANGE_VALID) {
return RUBY_ENC_CODERANGE_UNKNOWN;
}
else if (b == RUBY_ENC_CODERANGE_7BIT) {
return RUBY_ENC_CODERANGE_VALID;
}
else {
return b;
}
}
typedef unsigned char OnigUChar;
typedef unsigned int OnigCodePoint;
typedef unsigned int OnigCtype;
typedef size_t OnigDistance;
typedef ptrdiff_t OnigPosition;
typedef unsigned int OnigCaseFoldType;
extern OnigCaseFoldType OnigDefaultCaseFoldFlag;
typedef struct {
int byte_len;
int code_len;
OnigCodePoint code[3];
} OnigCaseFoldCodeItem;
typedef struct {
OnigCodePoint esc;
OnigCodePoint anychar;
OnigCodePoint anytime;
OnigCodePoint zero_or_one_time;
OnigCodePoint one_or_more_time;
OnigCodePoint anychar_anytime;
} OnigMetaCharTableType;
typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);
typedef struct OnigEncodingTypeST {
int (*precise_mbc_enc_len)(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
const char* name;
int max_enc_len;
int min_enc_len;
int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*code_to_mbclen)(OnigCodePoint code, const struct OnigEncodingTypeST* enc);
int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf, const struct OnigEncodingTypeST* enc);
int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, const struct OnigEncodingTypeST* enc);
int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, const struct OnigEncodingTypeST* enc);
int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[], const struct OnigEncodingTypeST* enc);
int (*property_name_to_ctype)(const struct OnigEncodingTypeST* enc, const OnigUChar* p, const OnigUChar* end);
int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype, const struct OnigEncodingTypeST* enc);
int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], const struct OnigEncodingTypeST* enc);
OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*case_map)(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
int ruby_encoding_index;
unsigned int flags;
} OnigEncodingType;
typedef const OnigEncodingType* OnigEncoding;
extern const OnigEncodingType OnigEncodingASCII;
extern
int onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
extern
int onigenc_mbclen(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
extern
OnigUChar* onigenc_step_back(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, int n);
extern
int onigenc_init(void);
extern
int onigenc_set_default_encoding(OnigEncoding enc);
extern
OnigEncoding onigenc_get_default_encoding(void);
extern
OnigUChar* onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, const OnigUChar** prev);
extern
OnigUChar* onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
extern
OnigUChar* onigenc_get_left_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
extern
OnigUChar* onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
extern
int onigenc_strlen(OnigEncoding enc, const OnigUChar* p, const OnigUChar* end);
extern
int onigenc_strlen_null(OnigEncoding enc, const OnigUChar* p);
extern
int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);
typedef unsigned int OnigOptionType;
typedef struct {
unsigned int op;
unsigned int op2;
unsigned int behavior;
OnigOptionType options;
OnigMetaCharTableType meta_char_table;
} OnigSyntaxType;
extern const OnigSyntaxType OnigSyntaxASIS;
extern const OnigSyntaxType OnigSyntaxPosixBasic;
extern const OnigSyntaxType OnigSyntaxPosixExtended;
extern const OnigSyntaxType OnigSyntaxEmacs;
extern const OnigSyntaxType OnigSyntaxGrep;
extern const OnigSyntaxType OnigSyntaxGnuRegex;
extern const OnigSyntaxType OnigSyntaxJava;
extern const OnigSyntaxType OnigSyntaxPerl58;
extern const OnigSyntaxType OnigSyntaxPerl58_NG;
extern const OnigSyntaxType OnigSyntaxPerl;
extern const OnigSyntaxType OnigSyntaxRuby;
extern const OnigSyntaxType OnigSyntaxPython;
extern const OnigSyntaxType* OnigDefaultSyntax;
struct re_registers {
int allocated;
int num_regs;
OnigPosition* beg;
OnigPosition* end;
};
typedef struct re_registers OnigRegion;
typedef struct {
OnigEncoding enc;
OnigUChar* par;
OnigUChar* par_end;
} OnigErrorInfo;
typedef struct {
int lower;
int upper;
long base_num;
long inner_num;
} OnigRepeatRange;
typedef void (*OnigWarnFunc)(const char* s);
extern void onig_null_warn(const char* s);
typedef struct re_pattern_buffer {
unsigned char* p;
unsigned int used;
unsigned int alloc;
int num_mem;
int num_repeat;
int num_null_check;
int num_comb_exp_check;
int num_call;
unsigned int capture_history;
unsigned int bt_mem_start;
unsigned int bt_mem_end;
int stack_pop_level;
int repeat_range_alloc;
OnigOptionType options;
OnigRepeatRange* repeat_range;
OnigEncoding enc;
const OnigSyntaxType* syntax;
void* name_table;
OnigCaseFoldType case_fold_flag;
int optimize;
int threshold_len;
int anchor;
OnigDistance anchor_dmin;
OnigDistance anchor_dmax;
int sub_anchor;
unsigned char *exact;
unsigned char *exact_end;
unsigned char map[256];
int *int_map;
int *int_map_backward;
OnigDistance dmin;
OnigDistance dmax;
uint64_t timelimit;
struct re_pattern_buffer* chain;
} OnigRegexType;
typedef OnigRegexType* OnigRegex;
typedef OnigRegexType regex_t;
typedef struct {
int num_of_elements;
OnigEncoding pattern_enc;
OnigEncoding target_enc;
const OnigSyntaxType* syntax;
OnigOptionType option;
OnigCaseFoldType case_fold_flag;
} OnigCompileInfo;
extern
int onig_initialize(OnigEncoding encodings[], int n);
extern
int onig_init(void);
extern
int onig_error_code_to_str(OnigUChar* s, OnigPosition err_code, ...);
extern
void onig_set_warn_func(OnigWarnFunc f);
extern
void onig_set_verb_warn_func(OnigWarnFunc f);
extern
int onig_new(OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
extern
int onig_reg_init(OnigRegex reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, const OnigSyntaxType* syntax);
extern
int onig_new_without_alloc(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
extern
int onig_new_deluxe(OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
extern
void onig_free(OnigRegex);
extern
void onig_free_body(OnigRegex);
extern
OnigPosition onig_scan(OnigRegex reg, const OnigUChar* str, const OnigUChar* end, OnigRegion* region, OnigOptionType option, int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*), void* callback_arg);
extern
OnigPosition onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
extern
OnigPosition onig_search_gpos(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* global_pos, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
extern
OnigPosition onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
extern
int onig_check_linear_time(OnigRegex reg);
extern
OnigRegion* onig_region_new(void);
extern
void onig_region_init(OnigRegion* region);
extern
void onig_region_free(OnigRegion* region, int free_self);
extern
void onig_region_copy(OnigRegion* to, const OnigRegion* from);
extern
void onig_region_clear(OnigRegion* region);
extern
int onig_region_resize(OnigRegion* region, int n);
extern
int onig_region_set(OnigRegion* region, int at, int beg, int end);
extern
int onig_name_to_group_numbers(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums);
extern
int onig_name_to_backref_number(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, const OnigRegion *region);
extern
int onig_foreach_name(OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg);
extern
int onig_number_of_names(const OnigRegexType *reg);
extern
int onig_number_of_captures(const OnigRegexType *reg);
extern
int onig_number_of_capture_histories(const OnigRegexType *reg);
extern
int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*), void* arg);
extern
int onig_noname_group_capture_is_active(const OnigRegexType *reg);
extern
OnigEncoding onig_get_encoding(const OnigRegexType *reg);
extern
OnigOptionType onig_get_options(const OnigRegexType *reg);
extern
OnigCaseFoldType onig_get_case_fold_flag(const OnigRegexType *reg);
extern
const OnigSyntaxType* onig_get_syntax(const OnigRegexType *reg);
extern
int onig_set_default_syntax(const OnigSyntaxType* syntax);
extern
void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
extern
unsigned int onig_get_syntax_op(const OnigSyntaxType* syntax);
extern
unsigned int onig_get_syntax_op2(const OnigSyntaxType* syntax);
extern
unsigned int onig_get_syntax_behavior(const OnigSyntaxType* syntax);
extern
OnigOptionType onig_get_syntax_options(const OnigSyntaxType* syntax);
extern
void onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op);
extern
void onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2);
extern
void onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior);
extern
void onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options);
extern
int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code);
extern
void onig_copy_encoding(OnigEncodingType *to, OnigEncoding from);
extern
OnigCaseFoldType onig_get_default_case_fold_flag(void);
extern
int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag);
extern
unsigned int onig_get_match_stack_limit_size(void);
extern
int onig_set_match_stack_limit_size(unsigned int size);
extern
unsigned int onig_get_parse_depth_limit(void);
extern
int onig_set_parse_depth_limit(unsigned int depth);
extern
int onig_end(void);
extern
const char* onig_version(void);
extern
const char* onig_copyright(void);
extern VALUE rb_cEncoding;
enum ruby_encoding_consts {
RUBY_ENCODING_INLINE_MAX = 127,
RUBY_ENCODING_SHIFT = (RUBY_FL_USHIFT+10),
RUBY_ENCODING_MASK = (RUBY_ENCODING_INLINE_MAX<<RUBY_ENCODING_SHIFT
),
RUBY_ENCODING_MAXNAMELEN = 42
};
static inline void
RB_ENCODING_SET_INLINED(VALUE obj, int encindex)
{
VALUE f = encindex;
f <<= RUBY_ENCODING_SHIFT;
RB_FL_UNSET_RAW(obj, RUBY_ENCODING_MASK);
RB_FL_SET_RAW(obj, f);
}
static inline int
RB_ENCODING_GET_INLINED(VALUE obj)
{
VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT;
return ((int)ret);
}
typedef const OnigEncodingType rb_encoding;
int rb_char_to_option_kcode(int c, int *option, int *kcode);
int rb_enc_replicate(const char *name, rb_encoding *src);
int rb_define_dummy_encoding(const char *name);
__attribute__((__pure__))
int rb_enc_dummy_p(rb_encoding *enc);
__attribute__((__pure__))
int rb_enc_to_index(rb_encoding *enc);
int rb_enc_get_index(VALUE obj);
static inline int
RB_ENCODING_GET(VALUE obj)
{
int encindex = RB_ENCODING_GET_INLINED(obj);
if (encindex == RUBY_ENCODING_INLINE_MAX) {
return rb_enc_get_index(obj);
}
else {
return encindex;
}
}
void rb_enc_set_index(VALUE obj, int encindex);
static inline void
RB_ENCODING_SET(VALUE obj, int encindex)
{
rb_enc_set_index(obj, encindex);
}
static inline void
RB_ENCODING_CODERANGE_SET(VALUE obj, int encindex, enum ruby_coderange_type cr)
{
RB_ENCODING_SET(obj, encindex);
RB_ENC_CODERANGE_SET(obj, cr);
}
__attribute__((__pure__))
int rb_enc_capable(VALUE obj);
int rb_enc_find_index(const char *name);
int rb_enc_alias(const char *alias, const char *orig);
int rb_to_encoding_index(VALUE obj);
rb_encoding *rb_to_encoding(VALUE obj);
rb_encoding *rb_find_encoding(VALUE obj);
rb_encoding *rb_enc_get(VALUE obj);
rb_encoding *rb_enc_compatible(VALUE str1, VALUE str2);
rb_encoding *rb_enc_check(VALUE str1,VALUE str2);
VALUE rb_enc_associate_index(VALUE obj, int encindex);
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc);
void rb_enc_copy(VALUE dst, VALUE src);
rb_encoding *rb_enc_from_index(int idx);
rb_encoding *rb_enc_find(const char *name);
static inline const char *
rb_enc_name(rb_encoding *enc)
{
return enc->name;
}
static inline int
rb_enc_mbminlen(rb_encoding *enc)
{
return enc->min_enc_len;
}
static inline int
rb_enc_mbmaxlen(rb_encoding *enc)
{
return enc->max_enc_len;
}
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc);
int rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc);
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc);
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc);
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len, rb_encoding *enc);
static inline unsigned int
rb_enc_codepoint(const char *p, const char *e, rb_encoding *enc)
{
return rb_enc_codepoint_len(p, e, 0, enc);
}
static inline OnigCodePoint
rb_enc_mbc_to_codepoint(const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *up = ((const OnigUChar *)p);
const OnigUChar *ue = ((const OnigUChar *)e);
return (enc)->mbc_to_code((up),(ue),enc);
}
int rb_enc_codelen(int code, rb_encoding *enc);
static inline int
rb_enc_code_to_mbclen(int c, rb_encoding *enc)
{
OnigCodePoint uc = ((OnigCodePoint)c);
return (enc)->code_to_mbclen(uc,enc);
}
static inline int
rb_enc_mbcput(unsigned int c, void *buf, rb_encoding *enc)
{
OnigCodePoint uc = ((OnigCodePoint)c);
OnigUChar *ubuf = ((OnigUChar *)buf);
return (enc)->code_to_mbc(uc,ubuf,enc);
}
static inline char *
rb_enc_prev_char(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = ((const OnigUChar *)s);
const OnigUChar *up = ((const OnigUChar *)p);
const OnigUChar *ue = ((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_prev_char_head(enc, us, up, ue);
return ((char *)ur);
}
static inline char *
rb_enc_left_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = ((const OnigUChar *)s);
const OnigUChar *up = ((const OnigUChar *)p);
const OnigUChar *ue = ((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_left_adjust_char_head(enc, us, up, ue);
return ((char *)ur);
}
static inline char *
rb_enc_right_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = ((const OnigUChar *)s);
const OnigUChar *up = ((const OnigUChar *)p);
const OnigUChar *ue = ((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_right_adjust_char_head(enc, us, up, ue);
return ((char *)ur);
}
static inline char *
rb_enc_step_back(const char *s, const char *p, const char *e, int n, rb_encoding *enc)
{
const OnigUChar *us = ((const OnigUChar *)s);
const OnigUChar *up = ((const OnigUChar *)p);
const OnigUChar *ue = ((const OnigUChar *)e);
const OnigUChar *ur = onigenc_step_back(enc, us, up, ue, n);
return ((char *)ur);
}
static inline int
rb_enc_asciicompat_inline(rb_encoding *enc)
{
return rb_enc_mbminlen(enc)==1 && !rb_enc_dummy_p(enc);
}
static inline _Bool
rb_enc_asciicompat(rb_encoding *enc)
{
if (rb_enc_mbminlen(enc) != 1) {
return 0;
}
else if (rb_enc_dummy_p(enc)) {
return 0;
}
else {
return 1;
}
}
static inline _Bool
rb_enc_str_asciicompat_p(VALUE str)
{
rb_encoding *enc = rb_enc_get(str);
return rb_enc_asciicompat(enc);
}
VALUE rb_enc_from_encoding(rb_encoding *enc);
__attribute__((__pure__))
int rb_enc_unicode_p(rb_encoding *enc);
__attribute__((__returns_nonnull__))
rb_encoding *rb_ascii8bit_encoding(void);
__attribute__((__returns_nonnull__))
rb_encoding *rb_utf8_encoding(void);
__attribute__((__returns_nonnull__))
rb_encoding *rb_usascii_encoding(void);
rb_encoding *rb_locale_encoding(void);
rb_encoding *rb_filesystem_encoding(void);
rb_encoding *rb_default_external_encoding(void);
rb_encoding *rb_default_internal_encoding(void);
__attribute__((__const__))
int rb_ascii8bit_encindex(void);
static inline _Bool
RB_ENCODING_IS_ASCII8BIT(VALUE obj)
{
return RB_ENCODING_GET_INLINED(obj) == rb_ascii8bit_encindex();
}
__attribute__((__const__))
int rb_utf8_encindex(void);
__attribute__((__const__))
int rb_usascii_encindex(void);
int rb_locale_encindex(void);
int rb_filesystem_encindex(void);
VALUE rb_enc_default_external(void);
VALUE rb_enc_default_internal(void);
void rb_enc_set_default_external(VALUE encoding);
void rb_enc_set_default_internal(VALUE encoding);
VALUE rb_locale_charmap(VALUE klass);
static inline _Bool
rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc)
{
OnigUChar *up = ((OnigUChar *)p);
OnigUChar *ue = ((OnigUChar *)e);
return (enc)->is_mbc_newline((up),(ue),enc);
}
static inline _Bool
rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,t,enc);
}
static inline _Bool
rb_enc_isascii(OnigCodePoint c, rb_encoding *enc)
{
return ((c) < 128);
}
static inline _Bool
rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,1,enc);
}
static inline _Bool
rb_enc_islower(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,6,enc);
}
static inline _Bool
rb_enc_isupper(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,10,enc);
}
static inline _Bool
rb_enc_iscntrl(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,3,enc);
}
static inline _Bool
rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,8,enc);
}
static inline _Bool
rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,13,enc);
}
static inline _Bool
rb_enc_isprint(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,7,enc);
}
static inline _Bool
rb_enc_isspace(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,9,enc);
}
static inline _Bool
rb_enc_isdigit(OnigCodePoint c, rb_encoding *enc)
{
return (enc)->is_code_ctype(c,4,enc);
}
__attribute__((__const__))
int rb_enc_toupper(int c, rb_encoding *enc);
__attribute__((__const__))
int rb_enc_tolower(int c, rb_encoding *enc);
__attribute__((__nonnull__ ()))
char *rb_enc_path_next(const char *path, const char *end, rb_encoding *enc);
__attribute__((__nonnull__ ()))
char *rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc);
__attribute__((__nonnull__ ()))
char *rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc);
__attribute__((__nonnull__ ()))
char *rb_enc_path_end(const char *path, const char *end, rb_encoding *enc);
__attribute__((__nonnull__ (1, 4)))
const char *ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encoding *enc);
__attribute__((__nonnull__ (1, 3)))
const char *ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc);
VALUE rb_enc_reg_new(const char *ptr, long len, rb_encoding *enc, int opts);
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 3)))
VALUE rb_enc_sprintf(rb_encoding *enc, const char *fmt, ...);
__attribute__((__nonnull__ (2)))
__attribute__((__format__(__printf__, 2, 0)))
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap);
__attribute__((__noreturn__))
__attribute__((__nonnull__ (3)))
__attribute__((__format__(__printf__, 3, 4)))
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...);
VALUE rb_enc_str_new(const char *ptr, long len, rb_encoding *enc);
__attribute__((__nonnull__ (1)))
VALUE rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc);
VALUE rb_enc_str_new_static(const char *ptr, long len, rb_encoding *enc);
VALUE rb_enc_interned_str(const char *ptr, long len, rb_encoding *enc);
__attribute__((__nonnull__ (1)))
VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc);
long rb_enc_strlen(const char *head, const char *tail, rb_encoding *enc);
char *rb_enc_nth(const char *head, const char *tail, long nth, rb_encoding *enc);
VALUE rb_obj_encoding(VALUE obj);
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc);
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc);
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *enc);
VALUE rb_str_export_to_enc(VALUE obj, rb_encoding *enc);
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to);
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts);
int rb_enc_str_coderange(VALUE str);
long rb_str_coderange_scan_restartable(const char *str, const char *end, rb_encoding *enc, int *cr);
int rb_enc_str_asciionly_p(VALUE str);
__attribute__((__nonnull__ ()))
long rb_memsearch(const void *x, long m, const void *y, long n, rb_encoding *enc);
__attribute__((__nonnull__ ()))
static inline VALUE
rbimpl_enc_str_new_cstr(const char *str, rb_encoding *enc)
{
long len = rbimpl_strlen(str);
return rb_enc_str_new_static(str, len, enc);
}
ID rb_intern3(const char *name, long len, rb_encoding *enc);
__attribute__((__nonnull__ ()))
int rb_enc_symname_p(const char *str, rb_encoding *enc);
int rb_enc_symname2_p(const char *name, long len, rb_encoding *enc);
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc);
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc);
typedef enum {
econv_invalid_byte_sequence,
econv_undefined_conversion,
econv_destination_buffer_full,
econv_source_buffer_empty,
econv_finished,
econv_after_output,
econv_incomplete_input
} rb_econv_result_t;
typedef struct rb_econv_t rb_econv_t;
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts);
int rb_econv_has_convpath_p(const char* from_encoding, const char* to_encoding);
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags);
int rb_econv_prepare_opts(VALUE opthash, VALUE *ecopts);
rb_econv_t *rb_econv_open(const char *source_encoding, const char *destination_encoding, int ecflags);
rb_econv_t *rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts);
rb_econv_result_t rb_econv_convert(rb_econv_t *ec,
const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end,
unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end,
int flags);
void rb_econv_close(rb_econv_t *ec);
int rb_econv_set_replacement(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname);
int rb_econv_decorate_at_first(rb_econv_t *ec, const char *decorator_name);
int rb_econv_decorate_at_last(rb_econv_t *ec, const char *decorator_name);
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags);
int rb_econv_insert_output(rb_econv_t *ec,
const unsigned char *str, size_t len, const char *str_encoding);
const char *rb_econv_encoding_to_insert_output(rb_econv_t *ec);
void rb_econv_check_error(rb_econv_t *ec);
VALUE rb_econv_make_exception(rb_econv_t *ec);
int rb_econv_putbackable(rb_econv_t *ec);
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n);
const char *rb_econv_asciicompat_encoding(const char *encname);
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags);
VALUE rb_econv_substr_convert(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, int flags);
VALUE rb_econv_str_append(rb_econv_t *ec, VALUE src, VALUE dst, int flags);
VALUE rb_econv_substr_append(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, VALUE dst, int flags);
VALUE rb_econv_append(rb_econv_t *ec, const char *bytesrc, long bytesize, VALUE dst, int flags);
void rb_econv_binmode(rb_econv_t *ec);
enum ruby_econv_flag_type {
RUBY_ECONV_ERROR_HANDLER_MASK = 0x000000ff,
RUBY_ECONV_INVALID_MASK = 0x0000000f,
RUBY_ECONV_INVALID_REPLACE = 0x00000002,
RUBY_ECONV_UNDEF_MASK = 0x000000f0,
RUBY_ECONV_UNDEF_REPLACE = 0x00000020,
RUBY_ECONV_UNDEF_HEX_CHARREF = 0x00000030,
RUBY_ECONV_DECORATOR_MASK = 0x0001ff00,
RUBY_ECONV_NEWLINE_DECORATOR_MASK = 0x00007f00,
RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK = 0x00000f00,
RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK = 0x00007000,
RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR = 0x00000100,
RUBY_ECONV_CRLF_NEWLINE_DECORATOR = 0x00001000,
RUBY_ECONV_CR_NEWLINE_DECORATOR = 0x00002000,
RUBY_ECONV_LF_NEWLINE_DECORATOR = 0x00004000,
RUBY_ECONV_XML_TEXT_DECORATOR = 0x00008000,
RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR = 0x00010000,
RUBY_ECONV_STATEFUL_DECORATOR_MASK = 0x00f00000,
RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR = 0x00100000,
RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR =
0,
RUBY_ECONV_PARTIAL_INPUT = 0x00020000,
RUBY_ECONV_AFTER_OUTPUT = 0x00040000,
RUBY_ECONV_FLAGS_PLACEHOLDER
};
VALUE rb_fstring(VALUE);
VALUE rb_fstring_cstr(const char *str);
VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc);
int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
int rb_str_symname_p(VALUE);
VALUE rb_str_quote_unprintable(VALUE);
char *rb_str_fill_terminator(VALUE str, const int termlen);
void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen);
VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
VALUE rb_str_chomp_string(VALUE str, VALUE chomp);
VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
rb_encoding *from, int ecflags, VALUE ecopts);
VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl);
VALUE rb_str_escape(VALUE str);
size_t rb_str_memsize(VALUE);
char *rb_str_to_cstr(VALUE str);
const char *ruby_escaped_char(int c);
void rb_str_make_independent(VALUE str);
int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc);
int rb_ascii8bit_appendable_encoding_index(rb_encoding *enc, unsigned int code);
VALUE rb_str_include(VALUE str, VALUE arg);
static inline _Bool STR_EMBED_P(VALUE str);
static inline _Bool STR_SHARED_P(VALUE str);
static inline VALUE QUOTE(VALUE v);
static inline VALUE QUOTE_ID(ID v);
static inline _Bool is_ascii_string(VALUE str);
static inline _Bool is_broken_string(VALUE str);
static inline VALUE rb_str_eql_internal(const VALUE str1, const VALUE str2);
VALUE rb_str_tmp_frozen_acquire(VALUE str);
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
void rb_str_make_embedded(VALUE);
size_t rb_str_size_as_embedded(VALUE);
_Bool rb_str_reembeddable_p(VALUE);
void rb_str_update_shared_ary(VALUE str, VALUE old_root, VALUE new_root);
VALUE rb_fstring_new(const char *ptr, long len);
VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
VALUE rb_str_opt_plus(VALUE x, VALUE y);
VALUE rb_str_concat_literals(size_t num, const VALUE *strary);
VALUE rb_str_eql(VALUE str1, VALUE str2);
VALUE rb_id_quote_unprintable(ID);
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc);
struct rb_execution_context_struct;
VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str);
static inline VALUE
QUOTE(VALUE v)
{
return rb_str_quote_unprintable(v);
}
static inline VALUE
QUOTE_ID(ID i)
{
return rb_id_quote_unprintable(i);
}
static inline _Bool
STR_EMBED_P(VALUE str)
{
return ! RB_FL_TEST_RAW(str, ((VALUE)RUBY_FL_USER1));
}
static inline _Bool
STR_SHARED_P(VALUE str)
{
return RB_FL_ALL_RAW(str, ((VALUE)RUBY_FL_USER1) | ((VALUE)RUBY_FL_USER2));
}
static inline _Bool
is_ascii_string(VALUE str)
{
return rb_enc_str_coderange(str) == RUBY_ENC_CODERANGE_7BIT;
}
static inline _Bool
is_broken_string(VALUE str)
{
return rb_enc_str_coderange(str) == RUBY_ENC_CODERANGE_BROKEN;
}
static inline VALUE
rb_str_eql_internal(const VALUE str1, const VALUE str2)
{
const long len = RSTRING_LEN(str1);
const char *ptr1, *ptr2;
if (len != RSTRING_LEN(str2)) return ((VALUE)RUBY_Qfalse);
if (!rb_str_comparable(str1, str2)) return ((VALUE)RUBY_Qfalse);
if ((ptr1 = RSTRING_PTR(str1)) == (ptr2 = RSTRING_PTR(str2)))
return ((VALUE)RUBY_Qtrue);
if (memcmp(ptr1, ptr2, len) == 0)
return ((VALUE)RUBY_Qtrue);
return ((VALUE)RUBY_Qfalse);
}
extern long rb_backtrace_length_limit;
extern VALUE rb_eEAGAIN;
extern VALUE rb_eEWOULDBLOCK;
extern VALUE rb_eEINPROGRESS;
__attribute__((__format__(__printf__, 3, 0)))
void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args);
__attribute__((__noreturn__)) void rb_async_bug_errno(const char *,int);
const char *rb_builtin_type_name(int t);
const char *rb_builtin_class_name(VALUE x);
__attribute__((__format__(__printf__, (1), (3)))) void rb_warn_deprecated(const char *fmt, const char *suggest, ...);
__attribute__((__format__(__printf__, (2), (4)))) void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const char *suggest, ...);
__attribute__((__format__(__printf__, 6, 0)))
VALUE rb_syntax_error_append(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
__attribute__((__format__(__printf__, (2), (3)))) void rb_enc_warn(rb_encoding *enc, const char *fmt, ...);
__attribute__((__format__(__printf__, (2), (3)))) void rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...);
__attribute__((__format__(__printf__, (3), (4)))) void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...);
rb_warning_category_t rb_warning_category_from_name(VALUE category);
_Bool rb_warning_category_enabled_p(rb_warning_category_t category);
VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
VALUE rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv);
VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
__attribute__((__format__(__printf__, (1), (2)))) VALUE rb_warning_string(const char *fmt, ...);
__attribute__((__format__(__printf__, 2, 0)))
__attribute__((__noreturn__)) void rb_vraise(VALUE, const char *, va_list);
__attribute__((__noreturn__)) static inline void rb_raise_cstr(VALUE etype, const char *mesg);
__attribute__((__noreturn__)) static inline void rb_raise_cstr_i(VALUE etype, VALUE mesg);
__attribute__((__noreturn__)) static inline void rb_name_err_raise_str(VALUE mesg, VALUE recv, VALUE name);
__attribute__((__noreturn__)) static inline void rb_name_err_raise(const char *mesg, VALUE recv, VALUE name);
__attribute__((__noreturn__)) static inline void rb_key_err_raise(VALUE mesg, VALUE recv, VALUE name);
static inline void Check_Type(VALUE v, enum ruby_value_type t);
static inline _Bool rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type);
int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
__attribute__((__noreturn__)) void rb_sys_fail_path_in(const char *func_name, VALUE path);
__attribute__((__noreturn__)) void rb_syserr_fail_path_in(const char *func_name, int err, VALUE path);
VALUE rb_syserr_new_path_in(const char *func_name, int n, VALUE path);
static inline void
rb_raise_cstr_i(VALUE etype, VALUE mesg)
{
VALUE exc = rb_exc_new_str(etype, mesg);
rb_exc_raise(exc);
}
static inline void
rb_raise_cstr(VALUE etype, const char *mesg)
{
VALUE str = ((__builtin_constant_p(mesg) ? rbimpl_str_new_cstr : rb_str_new_cstr) (mesg));
rb_raise_cstr_i(etype, str);
}
static inline void
rb_name_err_raise_str(VALUE mesg, VALUE recv, VALUE name)
{
VALUE exc = rb_name_err_new(mesg, recv, name);
rb_exc_raise(exc);
}
static inline void
rb_name_err_raise(const char *mesg, VALUE recv, VALUE name)
{
VALUE str = (__builtin_constant_p(mesg) ? rb_fstring_new((mesg), (long)strlen(mesg)) : (rb_fstring_cstr)(mesg));
rb_name_err_raise_str(str, recv, name);
}
static inline void
rb_key_err_raise(VALUE mesg, VALUE recv, VALUE name)
{
VALUE exc = rb_key_err_new(mesg, recv, name);
rb_exc_raise(exc);
}
static inline _Bool
rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type)
{
return RB_TYPE_P(obj, RUBY_T_DATA) && RTYPEDDATA_P(obj) && (RTYPEDDATA_TYPE(obj) == data_type);
}
extern ID ruby_static_id_signo;
extern ID ruby_static_id_status;
VALUE rb_refinement_module_get_refined_class(VALUE module);
void rb_class_modify_check(VALUE);
__attribute__((__noreturn__)) VALUE rb_f_raise(int argc, VALUE *argv);
VALUE rb_top_main_class(const char *method);
VALUE rb_get_backtrace(VALUE info);
void rb_call_end_proc(VALUE data);
void rb_mark_end_proc(void);
void Init_class_hierarchy(void);
void Init_enc(void);
void Init_ext(void);
void Init_File(void);
void Init_heap(void);
int Init_enc_set_filesystem_encoding(void);
void Init_newline(void);
void Init_BareVM(void);
void Init_vm_objects(void);
void Init_vm_backtrace(void);
void Init_vm_eval(void);static inline
void Init_vm_stack_canary(void);
void Init_eval_method(void);
void rb_call_inits(void);
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
__attribute__((__noreturn__)) void rb_undefined_alloc(VALUE klass);
double rb_num_to_dbl(VALUE val);
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
int rb_bool_expected(VALUE, const char *, int raise);
static inline void RBASIC_CLEAR_CLASS(VALUE obj);
static inline void RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass);
static inline void RBASIC_SET_CLASS(VALUE obj, VALUE klass);
int rb_opts_exception_p(VALUE opts, int default_value);
__attribute__((__const__)) VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
__attribute__((__const__)) VALUE rb_obj_not(VALUE obj);
VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
void rb_obj_copy_ivar(VALUE dest, VALUE obj);
VALUE rb_false(VALUE obj);
VALUE rb_convert_type_with_id(VALUE v, int t, const char* nam, ID mid);
VALUE rb_obj_size(VALUE self, VALUE args, VALUE obj);
VALUE rb_get_freeze_opt(int argc, VALUE *argv);
static inline void
RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
{
const VALUE *ptr = &((struct RBasic *)(obj))->klass;
*(VALUE *)ptr = klass;
}
static inline void
RBASIC_CLEAR_CLASS(VALUE obj)
{
RBASIC_SET_CLASS_RAW(obj, 0);
}
static inline void
RBASIC_SET_CLASS(VALUE obj, VALUE klass)
{
VALUE oldv = RBASIC_CLASS(obj);
RBASIC_SET_CLASS_RAW(obj, klass);
(rb_obj_written((VALUE)(obj), (VALUE)(oldv), (VALUE)(klass), "./internal/object.h", 59));
}
struct rb_iseq_struct;
VALUE rb_parser_set_yydebug(VALUE, VALUE);
void *rb_parser_load_file(VALUE parser, VALUE name);
void rb_parser_keep_script_lines(VALUE vparser);
void rb_parser_error_tolerant(VALUE vparser);
void rb_parser_keep_tokens(VALUE vparser);
VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
struct rb_block;
struct rb_iseq_struct;
VALUE rb_proc_location(VALUE self);
st_index_t rb_hash_proc(st_index_t hash, VALUE proc);
int rb_block_pair_yield_optimizable(void);
int rb_block_arity(void);
int rb_block_min_max_arity(int *max);
VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
VALUE rb_callable_receiver(VALUE);
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
VALUE rb_iseq_location(const struct rb_iseq_struct *iseq);
VALUE rb_sym_to_proc(VALUE sym);
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
VALUE rb_reg_check_preprocess(VALUE);
long rb_reg_search0(VALUE, VALUE, long, int, int);
VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
_Bool rb_reg_start_with_p(VALUE re, VALUE str);
VALUE rb_reg_hash(VALUE re);
VALUE rb_reg_equal(VALUE re1, VALUE re2);
void rb_backref_set_string(VALUE string, long pos, long len);
void rb_match_unbusy(VALUE);
int rb_match_count(VALUE match);
int rb_match_nth_defined(int nth, VALUE match);
VALUE rb_reg_new_ary(VALUE ary, int options);
VALUE rb_to_symbol_type(VALUE obj);
VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc);
VALUE rb_sym_intern_ascii(const char *ptr, long len);
VALUE rb_sym_intern_ascii_cstr(const char *ptr);
int rb_is_const_name(VALUE name);
int rb_is_class_name(VALUE name);
int rb_is_instance_name(VALUE name);
int rb_is_local_name(VALUE name);
__attribute__((__pure__)) int rb_is_const_sym(VALUE sym);
__attribute__((__pure__)) int rb_is_attrset_sym(VALUE sym);
ID rb_make_internal_id(void);
ID rb_make_temporary_id(size_t n);
void rb_gc_free_dsymbol(VALUE);
int rb_static_id_valid_p(ID id);
struct rb_thread_struct;
VALUE rb_obj_is_mutex(VALUE obj);
VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
void rb_thread_execute_interrupts(VALUE th);
VALUE rb_get_coverages(void);
int rb_get_coverage_mode(void);
VALUE rb_default_coverage(int);
VALUE rb_thread_shield_new(void);
_Bool rb_thread_shield_owned(VALUE self);
VALUE rb_thread_shield_wait(VALUE self);
VALUE rb_thread_shield_release(VALUE self);
VALUE rb_thread_shield_destroy(VALUE self);
int rb_thread_to_be_killed(VALUE thread);
void rb_mutex_allow_trap(VALUE self, int val);
VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
VALUE rb_mutex_owned_p(VALUE self);
VALUE rb_exec_recursive_outer_mid(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h, ID mid);
int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
int ruby_thread_has_gvl_p(void);
int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
typedef struct {
int coverage_sandboxed;
intptr_t coverage_fd;
unsigned int coverage_max_block_size;
} __sanitizer_sandbox_arguments;
void __sanitizer_set_report_path(const char *path);
void __sanitizer_set_report_fd(void *fd);
void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
void __sanitizer_report_error_summary(const char *error_summary);
uint16_t __sanitizer_unaligned_load16(const void *p);
uint32_t __sanitizer_unaligned_load32(const void *p);
uint64_t __sanitizer_unaligned_load64(const void *p);
void __sanitizer_unaligned_store16(void *p, uint16_t x);
void __sanitizer_unaligned_store32(void *p, uint32_t x);
void __sanitizer_unaligned_store64(void *p, uint64_t x);
void __sanitizer_annotate_contiguous_container(const void *beg,
const void *end,
const void *old_mid,
const void *new_mid);
int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
const void *end);
const void *__sanitizer_contiguous_container_find_bad_address(
const void *beg, const void *mid, const void *end);
void __sanitizer_print_stack_trace();
void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
size_t out_buf_size);
void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
char *out_buf, size_t out_buf_size);
void __sanitizer_set_death_callback(void (*callback)(void));
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
const void *s2, size_t n, int result);
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
const char *s2, size_t n, int result);
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
const char *s2, size_t n, int result);
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
const char *s2, int result);
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
const char *s2, int result);
void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
const char *s2, char *result);
void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
const char *s2, char *result);
void __sanitizer_weak_hook_memmem(void *called_pc,
const void *s1, size_t len1,
const void *s2, size_t len2, void *result);
void __sanitizer_print_memory_profile(size_t top_percent,
size_t max_number_of_contexts);
void __sanitizer_start_switch_fiber(void **fake_stack_save,
const void *bottom, size_t size);
void __sanitizer_finish_switch_fiber(void *fake_stack_save,
const void **bottom_old,
size_t *size_old);
int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
size_t module_path_len,
void **pc_offset);
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
int __asan_address_is_poisoned(void const volatile *addr);
void *__asan_region_is_poisoned(void *beg, size_t size);
void __asan_describe_address(void *addr);
int __asan_report_present();
void *__asan_get_report_pc();
void *__asan_get_report_bp();
void *__asan_get_report_sp();
void *__asan_get_report_address();
int __asan_get_report_access_type();
size_t __asan_get_report_access_size();
const char *__asan_get_report_description();
const char *__asan_locate_address(void *addr, char *name, size_t name_size,
void **region_address, size_t *region_size);
size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
int *thread_id);
size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
int *thread_id);
void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
void __asan_report_error(void *pc, void *bp, void *sp,
void *addr, int is_write, size_t access_size);
void __asan_set_death_callback(void (*callback)(void));
void __asan_set_error_report_callback(void (*callback)(const char*));
void __asan_on_error();
void __asan_print_accumulated_stats();
const char* __asan_default_options();
void *__asan_get_current_fake_stack();
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
void **end);
void __asan_handle_no_return(void);
struct rb_id_table;
enum rb_id_table_iterator_result {
ID_TABLE_CONTINUE = ST_CONTINUE,
ID_TABLE_STOP = ST_STOP,
ID_TABLE_DELETE = ST_DELETE,
ID_TABLE_REPLACE = ST_REPLACE,
ID_TABLE_ITERATOR_RESULT_END
};
struct rb_id_table *rb_id_table_create(size_t size);
void rb_id_table_free(struct rb_id_table *tbl);
void rb_id_table_clear(struct rb_id_table *tbl);
size_t rb_id_table_memsize(const struct rb_id_table *tbl);
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val);
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp);
int rb_id_table_delete(struct rb_id_table *tbl, ID id);
typedef enum rb_id_table_iterator_result rb_id_table_update_value_callback_func_t(VALUE *val, void *data, int existing);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE val, void *data);
typedef enum rb_id_table_iterator_result rb_id_table_foreach_values_func_t(VALUE val, void *data);
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data);
void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
void rb_id_table_foreach_values_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, rb_id_table_update_value_callback_func_t *replace, void *data);
size_t rb_id_table_size(const struct rb_id_table *tbl);
typedef enum {
CONST_DEPRECATED = 0x100,
CONST_VISIBILITY_MASK = 0xff,
CONST_PUBLIC = 0x00,
CONST_PRIVATE,
CONST_VISIBILITY_MAX
} rb_const_flag_t;
typedef struct rb_const_entry_struct {
rb_const_flag_t flag;
int line;
VALUE value;
VALUE file;
} rb_const_entry_t;
VALUE rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj);
VALUE rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj);
VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
void rb_free_const_table(struct rb_id_table *tbl);
VALUE rb_const_source_location(VALUE, ID);
int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
rb_const_entry_t *rb_const_lookup(VALUE klass, ID id);
VALUE rb_public_const_get_at(VALUE klass, ID id);
VALUE rb_public_const_get_from(VALUE klass, ID id);
int rb_public_const_defined_from(VALUE klass, ID id);
VALUE rb_const_source_location_at(VALUE, ID);
void rb_gc_mark_global_tbl(void);
void rb_gc_update_global_tbl(void);
size_t rb_generic_ivar_memsize(VALUE);
VALUE rb_search_class_path(VALUE);
VALUE rb_attr_delete(VALUE, ID);
void rb_autoload_str(VALUE mod, ID id, VALUE file);
VALUE rb_autoload_at_p(VALUE, ID, int);
__attribute__((__noreturn__)) VALUE rb_mod_const_missing(VALUE,VALUE);
rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
void rb_gvar_ractor_local(const char *name);
static inline _Bool ROBJ_TRANSIENT_P(VALUE obj);
static inline void ROBJ_TRANSIENT_SET(VALUE obj);
static inline void ROBJ_TRANSIENT_UNSET(VALUE obj);
struct gen_ivtbl;
int rb_gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl);
int rb_obj_evacuate_ivs_to_hash_table(ID key, VALUE val, st_data_t arg);
void rb_mark_generic_ivar(VALUE);
void rb_mv_generic_ivar(VALUE src, VALUE dst);
VALUE rb_const_missing(VALUE klass, VALUE name);
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
void rb_iv_tbl_copy(VALUE dst, VALUE src);
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
VALUE rb_gvar_get(ID);
VALUE rb_gvar_set(ID, VALUE);
VALUE rb_gvar_defined(ID);
void rb_const_warn_if_deprecated(const rb_const_entry_t *, VALUE, ID);
rb_shape_t * rb_grow_iv_list(VALUE obj);
void rb_ensure_iv_list_size(VALUE obj, uint32_t len, uint32_t newsize);
struct gen_ivtbl *rb_ensure_generic_iv_list_size(VALUE obj, rb_shape_t *shape, uint32_t newsize);
attr_index_t rb_obj_ivar_set(VALUE obj, ID id, VALUE val);
static inline _Bool
ROBJ_TRANSIENT_P(VALUE obj)
{
return RB_FL_TEST_RAW(obj, ((VALUE)RUBY_FL_USER2));
}
static inline void
ROBJ_TRANSIENT_SET(VALUE obj)
{
RB_FL_SET_RAW(obj, ((VALUE)RUBY_FL_USER2));
}
static inline void
ROBJ_TRANSIENT_UNSET(VALUE obj)
{
RB_FL_UNSET_RAW(obj, ((VALUE)RUBY_FL_USER2));
}
enum rb_mjit_func_state {
MJIT_FUNC_NOT_COMPILED = 0,
MJIT_FUNC_COMPILING = 1,
MJIT_FUNC_FAILED = 2,
};
struct mjit_options {
_Bool on;
_Bool save_temps;
_Bool warnings;
_Bool debug;
char* debug_flags;
_Bool wait;
unsigned int call_threshold;
int verbose;
int max_cache_size;
_Bool pause;
_Bool custom;
};
struct rb_mjit_compile_info {
_Bool disable_ivar_cache;
_Bool disable_exivar_cache;
_Bool disable_send_cache;
_Bool disable_inlining;
_Bool disable_const_cache;
};
typedef VALUE (*jit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
extern struct mjit_options mjit_opts;
extern _Bool mjit_call_p;
extern void rb_mjit_add_iseq_to_process(const rb_iseq_t *iseq);
extern struct rb_mjit_compile_info* rb_mjit_iseq_compile_info(const struct rb_iseq_constant_body *body);
extern void rb_mjit_recompile_send(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_ivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_exivar(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_inlining(const rb_iseq_t *iseq);
extern void rb_mjit_recompile_const(const rb_iseq_t *iseq);
extern void mjit_cancel_all(const char *reason);
extern _Bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id);
extern void mjit_init(const struct mjit_options *opts);
extern void mjit_free_iseq(const rb_iseq_t *iseq);
extern void mjit_update_references(const rb_iseq_t *iseq);
extern void mjit_mark(void);
extern void mjit_mark_cc_entries(const struct rb_iseq_constant_body *const body);
extern void mjit_notify_waitpid(int exit_code);
extern void rb_mjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop);
extern void rb_mjit_cme_invalidate(rb_callable_method_entry_t *cme);
extern void rb_mjit_before_ractor_spawn(void);
extern void rb_mjit_constant_state_changed(ID id);
extern void rb_mjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx);
extern void rb_mjit_tracing_invalidate_all(rb_event_flag_t new_iseq_events);
void mjit_child_after_fork(void);
VALUE mjit_pause(_Bool wait_p);
VALUE mjit_resume(void);
void mjit_finish(_Bool close_handle_p);
static inline _Bool rb_yjit_enabled_p(void) { return 0; }
static inline unsigned rb_yjit_call_threshold(void) { return (0x7fffffff * 2U + 1U); }
static inline void rb_yjit_invalidate_all_method_lookup_assumptions(void) {}
static inline void rb_yjit_cme_invalidate(rb_callable_method_entry_t *cme) {}
static inline void rb_yjit_collect_vm_usage_insn(int insn) {}
static inline void rb_yjit_collect_binding_alloc(void) {}
static inline void rb_yjit_collect_binding_set(void) {}
static inline _Bool rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec) { return 0; }
static inline void rb_yjit_init(void) {}
static inline void rb_yjit_bop_redefined(int redefined_flag, enum ruby_basic_operators bop) {}
static inline void rb_yjit_constant_state_changed(ID id) {}
static inline void rb_yjit_iseq_mark(void *payload) {}
static inline void rb_yjit_iseq_update_references(void *payload) {}
static inline void rb_yjit_iseq_free(void *payload) {}
static inline void rb_yjit_before_ractor_spawn(void) {}
static inline void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic, unsigned insn_idx) {}
static inline void rb_yjit_tracing_invalidate_all(void) {}
typedef struct rb_vm_struct ruby_vm_t;
int ruby_vm_destruct(ruby_vm_t *vm);
void ruby_vm_at_exit(void(*func)(ruby_vm_t *));
enum rb_debug_counter_type {
RB_DEBUG_COUNTER_mc_inline_hit,
RB_DEBUG_COUNTER_mc_inline_miss_klass,
RB_DEBUG_COUNTER_mc_inline_miss_invalidated,
RB_DEBUG_COUNTER_mc_inline_miss_empty,
RB_DEBUG_COUNTER_mc_inline_miss_same_cc,
RB_DEBUG_COUNTER_mc_inline_miss_same_cme,
RB_DEBUG_COUNTER_mc_inline_miss_same_def,
RB_DEBUG_COUNTER_mc_inline_miss_diff,
RB_DEBUG_COUNTER_cvar_write_inline_hit,
RB_DEBUG_COUNTER_cvar_read_inline_hit,
RB_DEBUG_COUNTER_cvar_inline_miss,
RB_DEBUG_COUNTER_cvar_class_invalidate,
RB_DEBUG_COUNTER_cvar_include_invalidate,
RB_DEBUG_COUNTER_mc_cme_complement,
RB_DEBUG_COUNTER_mc_cme_complement_hit,
RB_DEBUG_COUNTER_mc_search,
RB_DEBUG_COUNTER_mc_search_notfound,
RB_DEBUG_COUNTER_mc_search_super,
RB_DEBUG_COUNTER_ci_packed,
RB_DEBUG_COUNTER_ci_kw,
RB_DEBUG_COUNTER_ci_nokw,
RB_DEBUG_COUNTER_ci_runtime,
RB_DEBUG_COUNTER_cc_new,
RB_DEBUG_COUNTER_cc_temp,
RB_DEBUG_COUNTER_cc_found_in_ccs,
RB_DEBUG_COUNTER_cc_not_found_in_ccs,
RB_DEBUG_COUNTER_cc_ent_invalidate,
RB_DEBUG_COUNTER_cc_cme_invalidate,
RB_DEBUG_COUNTER_cc_invalidate_leaf,
RB_DEBUG_COUNTER_cc_invalidate_leaf_ccs,
RB_DEBUG_COUNTER_cc_invalidate_leaf_callable,
RB_DEBUG_COUNTER_cc_invalidate_tree,
RB_DEBUG_COUNTER_cc_invalidate_tree_cme,
RB_DEBUG_COUNTER_cc_invalidate_tree_callable,
RB_DEBUG_COUNTER_cc_invalidate_negative,
RB_DEBUG_COUNTER_ccs_free,
RB_DEBUG_COUNTER_ccs_maxlen,
RB_DEBUG_COUNTER_ccs_found,
RB_DEBUG_COUNTER_ccs_not_found,
RB_DEBUG_COUNTER_call0_public,
RB_DEBUG_COUNTER_call0_other,
RB_DEBUG_COUNTER_gccct_hit,
RB_DEBUG_COUNTER_gccct_miss,
RB_DEBUG_COUNTER_gccct_null,
RB_DEBUG_COUNTER_iseq_num,
RB_DEBUG_COUNTER_iseq_cd_num,
RB_DEBUG_COUNTER_ccf_general,
RB_DEBUG_COUNTER_ccf_iseq_setup,
RB_DEBUG_COUNTER_ccf_iseq_setup_0start,
RB_DEBUG_COUNTER_ccf_iseq_setup_tailcall_0start,
RB_DEBUG_COUNTER_ccf_iseq_fix,
RB_DEBUG_COUNTER_ccf_iseq_opt,
RB_DEBUG_COUNTER_ccf_iseq_kw1,
RB_DEBUG_COUNTER_ccf_iseq_kw2,
RB_DEBUG_COUNTER_ccf_cfunc,
RB_DEBUG_COUNTER_ccf_cfunc_with_frame,
RB_DEBUG_COUNTER_ccf_ivar,
RB_DEBUG_COUNTER_ccf_attrset,
RB_DEBUG_COUNTER_ccf_method_missing,
RB_DEBUG_COUNTER_ccf_zsuper,
RB_DEBUG_COUNTER_ccf_bmethod,
RB_DEBUG_COUNTER_ccf_opt_send,
RB_DEBUG_COUNTER_ccf_opt_call,
RB_DEBUG_COUNTER_ccf_opt_block_call,
RB_DEBUG_COUNTER_ccf_opt_struct_aref,
RB_DEBUG_COUNTER_ccf_opt_struct_aset,
RB_DEBUG_COUNTER_ccf_super_method,
RB_DEBUG_COUNTER_frame_push,
RB_DEBUG_COUNTER_frame_push_method,
RB_DEBUG_COUNTER_frame_push_block,
RB_DEBUG_COUNTER_frame_push_class,
RB_DEBUG_COUNTER_frame_push_top,
RB_DEBUG_COUNTER_frame_push_cfunc,
RB_DEBUG_COUNTER_frame_push_ifunc,
RB_DEBUG_COUNTER_frame_push_eval,
RB_DEBUG_COUNTER_frame_push_rescue,
RB_DEBUG_COUNTER_frame_push_dummy,
RB_DEBUG_COUNTER_frame_R2R,
RB_DEBUG_COUNTER_frame_R2C,
RB_DEBUG_COUNTER_frame_C2C,
RB_DEBUG_COUNTER_frame_C2R,
RB_DEBUG_COUNTER_ivar_get_ic_hit,
RB_DEBUG_COUNTER_ivar_get_ic_miss,
RB_DEBUG_COUNTER_ivar_get_ic_miss_noobject,
RB_DEBUG_COUNTER_ivar_set_ic_hit,
RB_DEBUG_COUNTER_ivar_set_ic_miss,
RB_DEBUG_COUNTER_ivar_set_ic_miss_iv_hit,
RB_DEBUG_COUNTER_ivar_set_ic_miss_noobject,
RB_DEBUG_COUNTER_ivar_get_base,
RB_DEBUG_COUNTER_ivar_set_base,
RB_DEBUG_COUNTER_ivar_get_ic_miss_set,
RB_DEBUG_COUNTER_ivar_get_cc_miss_set,
RB_DEBUG_COUNTER_ivar_get_ic_miss_unset,
RB_DEBUG_COUNTER_ivar_get_cc_miss_unset,
RB_DEBUG_COUNTER_lvar_get,
RB_DEBUG_COUNTER_lvar_get_dynamic,
RB_DEBUG_COUNTER_lvar_set,
RB_DEBUG_COUNTER_lvar_set_dynamic,
RB_DEBUG_COUNTER_lvar_set_slowpath,
RB_DEBUG_COUNTER_gc_count,
RB_DEBUG_COUNTER_gc_minor_newobj,
RB_DEBUG_COUNTER_gc_minor_malloc,
RB_DEBUG_COUNTER_gc_minor_method,
RB_DEBUG_COUNTER_gc_minor_capi,
RB_DEBUG_COUNTER_gc_minor_stress,
RB_DEBUG_COUNTER_gc_major_nofree,
RB_DEBUG_COUNTER_gc_major_oldgen,
RB_DEBUG_COUNTER_gc_major_shady,
RB_DEBUG_COUNTER_gc_major_force,
RB_DEBUG_COUNTER_gc_major_oldmalloc,
RB_DEBUG_COUNTER_gc_enter_start,
RB_DEBUG_COUNTER_gc_enter_mark_continue,
RB_DEBUG_COUNTER_gc_enter_sweep_continue,
RB_DEBUG_COUNTER_gc_enter_rest,
RB_DEBUG_COUNTER_gc_enter_finalizer,
RB_DEBUG_COUNTER_gc_isptr_trial,
RB_DEBUG_COUNTER_gc_isptr_range,
RB_DEBUG_COUNTER_gc_isptr_align,
RB_DEBUG_COUNTER_gc_isptr_maybe,
RB_DEBUG_COUNTER_obj_newobj,
RB_DEBUG_COUNTER_obj_newobj_slowpath,
RB_DEBUG_COUNTER_obj_newobj_wb_unprotected,
RB_DEBUG_COUNTER_obj_free,
RB_DEBUG_COUNTER_obj_promote,
RB_DEBUG_COUNTER_obj_wb_unprotect,
RB_DEBUG_COUNTER_obj_obj_embed,
RB_DEBUG_COUNTER_obj_obj_transient,
RB_DEBUG_COUNTER_obj_obj_ptr,
RB_DEBUG_COUNTER_obj_obj_too_complex,
RB_DEBUG_COUNTER_obj_str_ptr,
RB_DEBUG_COUNTER_obj_str_embed,
RB_DEBUG_COUNTER_obj_str_shared,
RB_DEBUG_COUNTER_obj_str_nofree,
RB_DEBUG_COUNTER_obj_str_fstr,
RB_DEBUG_COUNTER_obj_ary_embed,
RB_DEBUG_COUNTER_obj_ary_transient,
RB_DEBUG_COUNTER_obj_ary_ptr,
RB_DEBUG_COUNTER_obj_ary_extracapa,
RB_DEBUG_COUNTER_obj_ary_shared_create,
RB_DEBUG_COUNTER_obj_ary_shared,
RB_DEBUG_COUNTER_obj_ary_shared_root_occupied,
RB_DEBUG_COUNTER_obj_hash_empty,
RB_DEBUG_COUNTER_obj_hash_1,
RB_DEBUG_COUNTER_obj_hash_2,
RB_DEBUG_COUNTER_obj_hash_3,
RB_DEBUG_COUNTER_obj_hash_4,
RB_DEBUG_COUNTER_obj_hash_5_8,
RB_DEBUG_COUNTER_obj_hash_g8,
RB_DEBUG_COUNTER_obj_hash_null,
RB_DEBUG_COUNTER_obj_hash_ar,
RB_DEBUG_COUNTER_obj_hash_st,
RB_DEBUG_COUNTER_obj_hash_transient,
RB_DEBUG_COUNTER_obj_hash_force_convert,
RB_DEBUG_COUNTER_obj_struct_embed,
RB_DEBUG_COUNTER_obj_struct_transient,
RB_DEBUG_COUNTER_obj_struct_ptr,
RB_DEBUG_COUNTER_obj_data_empty,
RB_DEBUG_COUNTER_obj_data_xfree,
RB_DEBUG_COUNTER_obj_data_imm_free,
RB_DEBUG_COUNTER_obj_data_zombie,
RB_DEBUG_COUNTER_obj_match_under4,
RB_DEBUG_COUNTER_obj_match_ge4,
RB_DEBUG_COUNTER_obj_match_ge8,
RB_DEBUG_COUNTER_obj_match_ptr,
RB_DEBUG_COUNTER_obj_iclass_ptr,
RB_DEBUG_COUNTER_obj_class_ptr,
RB_DEBUG_COUNTER_obj_module_ptr,
RB_DEBUG_COUNTER_obj_bignum_ptr,
RB_DEBUG_COUNTER_obj_bignum_embed,
RB_DEBUG_COUNTER_obj_float,
RB_DEBUG_COUNTER_obj_complex,
RB_DEBUG_COUNTER_obj_rational,
RB_DEBUG_COUNTER_obj_regexp_ptr,
RB_DEBUG_COUNTER_obj_file_ptr,
RB_DEBUG_COUNTER_obj_symbol,
RB_DEBUG_COUNTER_obj_imemo_ment,
RB_DEBUG_COUNTER_obj_imemo_iseq,
RB_DEBUG_COUNTER_obj_imemo_env,
RB_DEBUG_COUNTER_obj_imemo_tmpbuf,
RB_DEBUG_COUNTER_obj_imemo_ast,
RB_DEBUG_COUNTER_obj_imemo_cref,
RB_DEBUG_COUNTER_obj_imemo_svar,
RB_DEBUG_COUNTER_obj_imemo_throw_data,
RB_DEBUG_COUNTER_obj_imemo_ifunc,
RB_DEBUG_COUNTER_obj_imemo_memo,
RB_DEBUG_COUNTER_obj_imemo_parser_strterm,
RB_DEBUG_COUNTER_obj_imemo_callinfo,
RB_DEBUG_COUNTER_obj_imemo_callcache,
RB_DEBUG_COUNTER_obj_imemo_constcache,
RB_DEBUG_COUNTER_artable_hint_hit,
RB_DEBUG_COUNTER_artable_hint_miss,
RB_DEBUG_COUNTER_artable_hint_notfound,
RB_DEBUG_COUNTER_heap_xmalloc,
RB_DEBUG_COUNTER_heap_xrealloc,
RB_DEBUG_COUNTER_heap_xfree,
RB_DEBUG_COUNTER_theap_alloc,
RB_DEBUG_COUNTER_theap_alloc_fail,
RB_DEBUG_COUNTER_theap_evacuate,
RB_DEBUG_COUNTER_vm_sync_lock,
RB_DEBUG_COUNTER_vm_sync_lock_enter,
RB_DEBUG_COUNTER_vm_sync_lock_enter_nb,
RB_DEBUG_COUNTER_vm_sync_lock_enter_cr,
RB_DEBUG_COUNTER_vm_sync_barrier,
RB_DEBUG_COUNTER_MAX
};
void rb_debug_counter_show_results(const char *msg);
size_t ruby_debug_counter_get(const char **names_ptr, size_t *counters_ptr);
void ruby_debug_counter_reset(void);
void ruby_debug_counter_show_at_exit(int enable);
struct rb_subclass_entry {
VALUE klass;
struct rb_subclass_entry *next;
struct rb_subclass_entry *prev;
};
struct rb_cvar_class_tbl_entry {
uint32_t index;
rb_serial_t global_cvar_state;
const rb_cref_t * cref;
VALUE class_value;
};
struct rb_classext_struct {
VALUE *iv_ptr;
struct rb_id_table *const_tbl;
struct rb_id_table *callable_m_tbl;
struct rb_id_table *cc_tbl;
struct rb_id_table *cvc_tbl;
size_t superclass_depth;
VALUE *superclasses;
struct rb_subclass_entry *subclasses;
struct rb_subclass_entry *subclass_entry;
struct rb_subclass_entry *module_subclass_entry;
const VALUE origin_;
const VALUE refined_class;
rb_alloc_func_t allocator;
const VALUE includer;
uint32_t max_iv_count;
uint32_t variation_count;
};
struct RClass {
struct RBasic basic;
VALUE super;
struct rb_id_table *m_tbl;
};
typedef struct rb_subclass_entry rb_subclass_entry_t;
typedef struct rb_classext_struct rb_classext_t;
void rb_class_subclass_add(VALUE super, VALUE klass);
void rb_class_remove_from_super_subclasses(VALUE);
void rb_class_update_superclasses(VALUE);
size_t rb_class_superclasses_memsize(VALUE);
void rb_class_remove_subclass_head(VALUE);
int rb_singleton_class_internal_p(VALUE sklass);
VALUE rb_class_boot(VALUE);
VALUE rb_class_s_alloc(VALUE klass);
VALUE rb_module_s_alloc(VALUE klass);
void rb_module_set_initialized(VALUE module);
void rb_module_check_initializable(VALUE module);
VALUE rb_make_metaclass(VALUE, VALUE);
VALUE rb_include_class_new(VALUE, VALUE);
void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
void rb_class_detach_subclasses(VALUE);
void rb_class_detach_module_subclasses(VALUE);
void rb_class_remove_from_module_subclasses(VALUE);
VALUE rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super);
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
VALUE rb_class_undefined_instance_methods(VALUE mod);
VALUE rb_special_singleton_class(VALUE);
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
VALUE rb_singleton_class_get(VALUE obj);
void rb_undef_methods_from(VALUE klass, VALUE super);
static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
static inline VALUE RCLASS_SUPER(VALUE klass);
static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
VALUE rb_class_inherited(VALUE, VALUE);
VALUE rb_keyword_error_new(const char *, VALUE);
static inline void
RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
{
rb_obj_write((VALUE)(klass), ((VALUE *)(&(((rb_classext_t *)((char *)(klass) + sizeof(struct RClass)))->origin_))), (VALUE)(origin), "./internal/class.h", 147);
if (klass != origin) RB_FL_SET(origin, ((VALUE)RUBY_FL_USER0));
}
static inline void
RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
{
RB_FL_SET(iclass, ((VALUE)RUBY_FL_USER3));
}
static inline _Bool
RICLASS_OWNS_M_TBL_P(VALUE iclass)
{
return RB_FL_TEST_RAW(iclass, ((VALUE)RUBY_FL_USER0) | ((VALUE)RUBY_FL_USER3)) == ((VALUE)RUBY_FL_USER0);
}
static inline void
RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
{
rb_obj_write((VALUE)(iclass), ((VALUE *)(&(((rb_classext_t *)((char *)(iclass) + sizeof(struct RClass)))->includer))), (VALUE)(klass), "./internal/class.h", 166);
}
static inline VALUE
RCLASS_SUPER(VALUE klass)
{
return ((struct RClass *)(klass))->super;
}
static inline VALUE
RCLASS_SET_SUPER(VALUE klass, VALUE super)
{
if (super) {
rb_class_remove_from_super_subclasses(klass);
rb_class_subclass_add(super, klass);
}
rb_obj_write((VALUE)(klass), ((VALUE *)(&((struct RClass *)(klass))->super)), (VALUE)(super), "./internal/class.h", 182);
rb_class_update_superclasses(klass);
return super;
}
enum vm_call_flag_bits {
VM_CALL_ARGS_SPLAT_bit,
VM_CALL_ARGS_BLOCKARG_bit,
VM_CALL_FCALL_bit,
VM_CALL_VCALL_bit,
VM_CALL_ARGS_SIMPLE_bit,
VM_CALL_BLOCKISEQ_bit,
VM_CALL_KWARG_bit,
VM_CALL_KW_SPLAT_bit,
VM_CALL_TAILCALL_bit,
VM_CALL_SUPER_bit,
VM_CALL_ZSUPER_bit,
VM_CALL_OPT_SEND_bit,
VM_CALL_KW_SPLAT_MUT_bit,
VM_CALL__END
};
struct rb_callinfo_kwarg {
int keyword_len;
VALUE keywords[];
};
static inline size_t
rb_callinfo_kwarg_bytes(int keyword_len)
{
return rb_size_mul_add_or_raise(
keyword_len,
sizeof(VALUE),
sizeof(struct rb_callinfo_kwarg),
rb_eRuntimeError);
}
struct rb_callinfo {
VALUE flags;
const struct rb_callinfo_kwarg *kwarg;
VALUE mid;
VALUE flag;
VALUE argc;
};
static inline _Bool
vm_ci_packed_p(const struct rb_callinfo *ci)
{
if ((__builtin_expect(!!(((VALUE)ci) & 0x01), 1))) {
return 1;
}
else {
((void)0);
return 0;
}
}
static inline _Bool
vm_ci_p(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci) || imemo_type_p((VALUE)ci, imemo_callinfo)) {
return 1;
}
else {
return 0;
}
}
static inline ID
vm_ci_mid(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci)) {
return (((VALUE)ci) >> (1 + 15 + 16)) & ((((VALUE)1)<<32) - 1);
}
else {
return (ID)ci->mid;
}
}
static inline unsigned int
vm_ci_flag(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci)) {
return (unsigned int)((((VALUE)ci) >> (1 + 15)) & ((((VALUE)1)<<16) - 1));
}
else {
return (unsigned int)ci->flag;
}
}
static inline unsigned int
vm_ci_argc(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci)) {
return (unsigned int)((((VALUE)ci) >> (1)) & ((((VALUE)1)<<15) - 1));
}
else {
return (unsigned int)ci->argc;
}
}
static inline const struct rb_callinfo_kwarg *
vm_ci_kwarg(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci)) {
return ((void *)0);
}
else {
return ci->kwarg;
}
}
static inline void
vm_ci_dump(const struct rb_callinfo *ci)
{
if (vm_ci_packed_p(ci)) {
ruby_debug_printf("packed_ci ID:%s flag:%x argc:%u\n",
rb_id2name(vm_ci_mid(ci)), vm_ci_flag(ci), vm_ci_argc(ci));
}
else {
rb_obj_info_dump_loc((VALUE)(ci), "./vm_callinfo.h", 177, __func__);
}
}
static inline const struct rb_callinfo *
vm_ci_new_(ID mid, unsigned int flag, unsigned int argc, const struct rb_callinfo_kwarg *kwarg, const char *file, int line)
{
if ((((mid ) & ~((((VALUE)1)<<32) - 1)) ? 0 : ((flag) & ~((((VALUE)1)<<16) - 1)) ? 0 : ((argc) & ~((((VALUE)1)<<15) - 1)) ? 0 : (kwarg) ? 0 : 1)) {
((void)0);
return ((const struct rb_callinfo *) ((((VALUE)(mid )) << (1 + 15 + 16)) | (((VALUE)(flag)) << (1 + 15)) | (((VALUE)(argc)) << (1)) | RUBY_FIXNUM_FLAG));
}
const _Bool debug = 0;
if (debug) ruby_debug_printf("%s:%d ", file, line);
const struct rb_callinfo *ci = (const struct rb_callinfo *)
rb_imemo_new(imemo_callinfo,
(VALUE)mid,
(VALUE)flag,
(VALUE)argc,
(VALUE)kwarg);
if (debug) rb_obj_info_dump_loc((VALUE)(ci), "./vm_callinfo.h", 218, __func__);
if (kwarg) {
((void)0);
}
else {
((void)0);
}
((void)0);
((void)0);
return ci;
}
static inline const struct rb_callinfo *
vm_ci_new_runtime_(ID mid, unsigned int flag, unsigned int argc, const struct rb_callinfo_kwarg *kwarg, const char *file, int line)
{
((void)0);
return vm_ci_new_(mid, flag, argc, kwarg, file, line);
}
static inline _Bool
vm_ci_markable(const struct rb_callinfo *ci)
{
if (! ci) {
return 0;
}
else if (vm_ci_packed_p(ci)) {
return 1;
}
else {
((void)0);
return ! RB_FL_ANY_RAW((VALUE)ci, ((VALUE)RUBY_FL_USER4));
}
}
typedef VALUE (*vm_call_handler)(
struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *cfp,
struct rb_calling_info *calling);
struct rb_callcache {
const VALUE flags;
const VALUE klass;
const struct rb_callable_method_entry_struct * const cme_;
const vm_call_handler call_;
union {
struct {
uintptr_t value;
} attr;
const enum method_missing_reason method_missing_reason;
VALUE v;
} aux_;
};
extern const struct rb_callcache *rb_vm_empty_cc(void);
extern const struct rb_callcache *rb_vm_empty_cc_for_super(void);
static inline void vm_cc_attr_index_set(const struct rb_callcache *cc, attr_index_t index, shape_id_t dest_shape_id);
static inline void
vm_cc_attr_index_initialize(const struct rb_callcache *cc, shape_id_t shape_id)
{
vm_cc_attr_index_set(cc, (attr_index_t)-1, shape_id);
}
static inline const struct rb_callcache *
vm_cc_new(VALUE klass,
const struct rb_callable_method_entry_struct *cme,
vm_call_handler call)
{
const struct rb_callcache *cc = (const struct rb_callcache *)rb_imemo_new(imemo_callcache, (VALUE)cme, (VALUE)call, 0, klass);
vm_cc_attr_index_initialize(cc, (((uintptr_t)1 << 32) - 1));
((void)0);
return cc;
}
static inline _Bool
vm_cc_class_check(const struct rb_callcache *cc, VALUE klass)
{
((void)0);
((void)0);
return cc->klass == klass;
}
static inline int
vm_cc_markable(const struct rb_callcache *cc)
{
((void)0);
return RB_FL_TEST_RAW((VALUE)cc, ((VALUE)RUBY_FL_FREEZE)) == 0;
}
static inline const struct rb_callable_method_entry_struct *
vm_cc_cme(const struct rb_callcache *cc)
{
((void)0);
((void)0);
return cc->cme_;
}
static inline vm_call_handler
vm_cc_call(const struct rb_callcache *cc)
{
((void)0);
((void)0);
return cc->call_;
}
static inline attr_index_t
vm_cc_attr_index(const struct rb_callcache *cc)
{
((void)0);
return (attr_index_t)((cc->aux_.attr.value & (((VALUE)-1) >> 32)) - 1);
}
static inline shape_id_t
vm_cc_attr_index_dest_shape_id(const struct rb_callcache *cc)
{
((void)0);
return cc->aux_.attr.value >> ((8 * 8) - 32);
}
static inline void
vm_cc_atomic_shape_and_index(const struct rb_callcache *cc, shape_id_t * shape_id, attr_index_t * index)
{
uintptr_t cache_value = cc->aux_.attr.value;
*shape_id = (shape_id_t)(cache_value >> ((8 * 8) - 32));
*index = (attr_index_t)(cache_value & (((VALUE)-1) >> 32)) - 1;
return;
}
static inline void
vm_ic_atomic_shape_and_index(const struct iseq_inline_iv_cache_entry *ic, shape_id_t * shape_id, attr_index_t * index)
{
uintptr_t cache_value = ic->value;
*shape_id = (shape_id_t)(cache_value >> ((8 * 8) - 32));
*index = (attr_index_t)(cache_value & (((VALUE)-1) >> 32)) - 1;
return;
}
static inline shape_id_t
vm_ic_attr_index_dest_shape_id(const struct iseq_inline_iv_cache_entry *ic)
{
return (shape_id_t)(ic->value >> ((8 * 8) - 32));
}
static inline unsigned int
vm_cc_cmethod_missing_reason(const struct rb_callcache *cc)
{
((void)0);
return cc->aux_.method_missing_reason;
}
static inline _Bool
vm_cc_invalidated_p(const struct rb_callcache *cc)
{
if (cc->klass && !((vm_cc_cme(cc))->flags & ((VALUE)RUBY_FL_USER9))) {
return 0;
}
else {
return 1;
}
}
static inline _Bool
vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *cc_cme, VALUE klass)
{
((void)0);
if (cc->klass == klass && !((cc_cme)->flags & ((VALUE)RUBY_FL_USER9))) {
return 1;
}
else {
return 0;
}
}
static inline void
vm_cc_call_set(const struct rb_callcache *cc, vm_call_handler call)
{
((void)0);
((void)0);
*(vm_call_handler *)&cc->call_ = call;
}
static inline void
vm_cc_attr_index_set(const struct rb_callcache *cc, attr_index_t index, shape_id_t dest_shape_id)
{
uintptr_t *attr_value = (uintptr_t *)&cc->aux_.attr.value;
if (!vm_cc_markable(cc)) {
*attr_value = (uintptr_t)(((uintptr_t)1 << 32) - 1) << ((8 * 8) - 32);
return;
}
((void)0);
((void)0);
*attr_value = (attr_index_t)(index + 1) | ((uintptr_t)(dest_shape_id) << ((8 * 8) - 32));
}
static inline void
vm_ic_attr_index_set(const rb_iseq_t *iseq, const struct iseq_inline_iv_cache_entry *ic, attr_index_t index, shape_id_t dest_shape_id)
{
*(uintptr_t *)&ic->value = ((uintptr_t)dest_shape_id << ((8 * 8) - 32)) | (attr_index_t)(index + 1);
}
static inline void
vm_ic_attr_index_initialize(const struct iseq_inline_iv_cache_entry *ic, shape_id_t shape_id)
{
*(uintptr_t *)&ic->value = (uintptr_t)shape_id << ((8 * 8) - 32);
}
static inline void
vm_cc_method_missing_reason_set(const struct rb_callcache *cc, enum method_missing_reason reason)
{
((void)0);
((void)0);
*(enum method_missing_reason *)&cc->aux_.method_missing_reason = reason;
}
static inline void
vm_cc_invalidate(const struct rb_callcache *cc)
{
((void)0);
((void)0);
((void)0);
*(VALUE *)&cc->klass = 0;
((void)0);
}
struct rb_call_data {
const struct rb_callinfo *ci;
const struct rb_callcache *cc;
};
struct rb_class_cc_entries {
int capa;
int len;
const struct rb_callable_method_entry_struct *cme;
struct rb_class_cc_entries_entry {
const struct rb_callinfo *ci;
const struct rb_callcache *cc;
} *entries;
};
void rb_vm_ccs_free(struct rb_class_cc_entries *ccs);
struct RNode;
VALUE ruby_debug_print_value(int level, int debug_level, const char *header, VALUE v);
ID ruby_debug_print_id(int level, int debug_level, const char *header, ID id);
struct RNode *ruby_debug_print_node(int level, int debug_level, const char *header, const struct RNode *node);
int ruby_debug_print_indent(int level, int debug_level, int indent_level);
void ruby_debug_gc_check_func(void);
void ruby_set_debug_option(const char *str);
extern enum ruby_debug_log_mode {
ruby_debug_log_disabled = 0x00,
ruby_debug_log_memory = 0x01,
ruby_debug_log_stderr = 0x02,
ruby_debug_log_file = 0x04,
} ruby_debug_log_mode;
__attribute__((__format__(__printf__, 4, 5)))
void ruby_debug_log(const char *file, int line, const char *func_name, const char *fmt, ...);
void ruby_debug_log_print(unsigned int n);
_Bool ruby_debug_log_filter(const char *func_name, const char *file_name);
typedef long OFFSET;
typedef unsigned long lindex_t;
typedef VALUE GENTRY;
typedef rb_iseq_t *ISEQ;
extern VALUE ruby_vm_const_missing_count;
extern rb_serial_t ruby_vm_constant_cache_invalidations;
extern rb_serial_t ruby_vm_constant_cache_misses;
extern rb_serial_t ruby_vm_global_cvar_state;
static inline void
CC_SET_FASTPATH(const struct rb_callcache *cc, vm_call_handler func, _Bool enabled)
{
if ((__builtin_expect(!!(enabled), 1))) {
vm_cc_call_set(cc, func);
}
}
static inline struct vm_throw_data *
THROW_DATA_NEW(VALUE val, const rb_control_frame_t *cf, int st)
{
struct vm_throw_data *obj = (struct vm_throw_data *)rb_imemo_new(imemo_throw_data, val, (VALUE)cf, 0, 0);
obj->throw_state = st;
return obj;
}
static inline VALUE
THROW_DATA_VAL(const struct vm_throw_data *obj)
{
((void)0);
return obj->throw_obj;
}
static inline const rb_control_frame_t *
THROW_DATA_CATCH_FRAME(const struct vm_throw_data *obj)
{
((void)0);
return obj->catch_frame;
}
static inline int
THROW_DATA_STATE(const struct vm_throw_data *obj)
{
((void)0);
return obj->throw_state;
}
static inline int
THROW_DATA_CONSUMED_P(const struct vm_throw_data *obj)
{
((void)0);
return obj->flags & ((VALUE)RUBY_FL_USER4);
}
static inline void
THROW_DATA_CATCH_FRAME_SET(struct vm_throw_data *obj, const rb_control_frame_t *cfp)
{
((void)0);
obj->catch_frame = cfp;
}
static inline void
THROW_DATA_STATE_SET(struct vm_throw_data *obj, int st)
{
((void)0);
obj->throw_state = st;
}
static inline void
THROW_DATA_CONSUMED_SET(struct vm_throw_data *obj)
{
if (imemo_throw_data_p((VALUE)obj) &&
THROW_DATA_STATE(obj) == RUBY_TAG_BREAK) {
obj->flags |= ((VALUE)RUBY_FL_USER4);
}
}
static inline _Bool
vm_call_cacheable(const struct rb_callinfo *ci, const struct rb_callcache *cc)
{
return (vm_ci_flag(ci) & (0x01 << VM_CALL_FCALL_bit)) ||
(rb_method_visibility_t)(((vm_cc_cme(cc))->flags & (((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+0)) != METHOD_VISI_PROTECTED;
}
static inline _Bool
vm_call_iseq_optimizable_p(const struct rb_callinfo *ci, const struct rb_callcache *cc)
{
return !(vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit)) && !(vm_ci_flag(ci) & (0x01 << VM_CALL_KWARG_bit)) && vm_call_cacheable(ci, cc);
}
struct rb_ractor_local_storage_type {
void (*mark)(void *ptr);
void (*free)(void *ptr);
};
typedef struct rb_ractor_local_key_struct *rb_ractor_local_key_t;
extern VALUE rb_cRactor;
VALUE rb_ractor_stdin(void);
VALUE rb_ractor_stdout(void);
VALUE rb_ractor_stderr(void);
void rb_ractor_stdin_set(VALUE io);
void rb_ractor_stdout_set(VALUE io);
void rb_ractor_stderr_set(VALUE io);
rb_ractor_local_key_t rb_ractor_local_storage_value_newkey(void);
VALUE rb_ractor_local_storage_value(rb_ractor_local_key_t key);
_Bool rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val);
void rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val);
extern const struct rb_ractor_local_storage_type rb_ractor_local_storage_type_free;
rb_ractor_local_key_t rb_ractor_local_storage_ptr_newkey(const struct rb_ractor_local_storage_type *type);
void *rb_ractor_local_storage_ptr(rb_ractor_local_key_t key);
void rb_ractor_local_storage_ptr_set(rb_ractor_local_key_t key, void *ptr);
VALUE rb_ractor_make_shareable(VALUE obj);
VALUE rb_ractor_make_shareable_copy(VALUE obj);
static inline _Bool
rb_ractor_shareable_p(VALUE obj)
{
_Bool rb_ractor_shareable_p_continue(VALUE obj);
if (RB_SPECIAL_CONST_P(obj)) {
return 1;
}
else if (RB_FL_TEST_RAW((obj), RUBY_FL_SHAREABLE)) {
return 1;
}
else {
return rb_ractor_shareable_p_continue(obj);
}
}
enum rb_ractor_basket_type {
basket_type_none,
basket_type_ref,
basket_type_copy,
basket_type_move,
basket_type_will,
basket_type_deleted,
basket_type_reserved,
};
struct rb_ractor_basket {
_Bool exception;
enum rb_ractor_basket_type type;
VALUE v;
VALUE sender;
};
struct rb_ractor_queue {
struct rb_ractor_basket *baskets;
int start;
int cnt;
int size;
unsigned int serial;
unsigned int reserved_cnt;
};
struct rb_ractor_waiting_list {
int cnt;
int size;
rb_ractor_t **ractors;
};
enum rb_ractor_wait_status {
wait_none = 0x00,
wait_receiving = 0x01,
wait_taking = 0x02,
wait_yielding = 0x04,
wait_moving = 0x08,
};
enum rb_ractor_wakeup_status {
wakeup_none,
wakeup_by_send,
wakeup_by_yield,
wakeup_by_take,
wakeup_by_close,
wakeup_by_interrupt,
wakeup_by_retry,
};
struct rb_ractor_sync {
rb_nativethread_lock_t lock;
rb_nativethread_cond_t cond;
struct rb_ractor_queue incoming_queue;
struct rb_ractor_waiting_list taking_ractors;
_Bool incoming_port_closed;
_Bool outgoing_port_closed;
struct ractor_wait {
enum rb_ractor_wait_status status;
enum rb_ractor_wakeup_status wakeup_status;
struct rb_ractor_basket yielded_basket;
struct rb_ractor_basket taken_basket;
} wait;
};
enum ractor_status {
ractor_created,
ractor_running,
ractor_blocking,
ractor_terminated,
};
struct rb_ractor_struct {
struct rb_ractor_pub pub;
struct rb_ractor_sync sync;
VALUE receiving_mutex;
_Bool yield_atexit;
rb_nativethread_cond_t barrier_wait_cond;
struct {
struct ccan_list_head set;
unsigned int cnt;
unsigned int blocking_cnt;
unsigned int sleeper;
struct rb_thread_sched sched;
rb_execution_context_t *running_ec;
rb_thread_t *main;
} threads;
VALUE thgroup_default;
VALUE name;
VALUE loc;
enum ractor_status status_;
struct ccan_list_node vmlr_node;
st_table *local_storage;
struct rb_id_table *idkey_local_storage;
VALUE r_stdin;
VALUE r_stdout;
VALUE r_stderr;
VALUE verbose;
VALUE debug;
rb_ractor_newobj_cache_t newobj_cache;
struct gc_mark_func_data_struct {
void *data;
void (*mark_func)(VALUE v, void *data);
} *mfd;
};
static inline VALUE
rb_ractor_self(const rb_ractor_t *r)
{
return r->pub.self;
}
rb_ractor_t *rb_ractor_main_alloc(void);
void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread);
void rb_ractor_atexit(rb_execution_context_t *ec, VALUE result);
void rb_ractor_atexit_exception(rb_execution_context_t *ec);
void rb_ractor_teardown(rb_execution_context_t *ec);
void rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *g, int len, VALUE *ptr);
void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE args);
VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc);
int rb_ractor_living_thread_num(const rb_ractor_t *);
VALUE rb_ractor_thread_list(rb_ractor_t *r);
_Bool rb_ractor_p(VALUE rv);
void rb_ractor_living_threads_init(rb_ractor_t *r);
void rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th);
void rb_ractor_living_threads_remove(rb_ractor_t *r, rb_thread_t *th);
void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line);
void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line);
void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r);
void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r);
void rb_ractor_terminate_all(void);
_Bool rb_ractor_main_p_(void);
void rb_ractor_finish_marking(void);
void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th);
VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name);
_Bool rb_ractor_shareable_p_continue(VALUE obj);
void rb_ractor_local_storage_delkey(rb_ractor_local_key_t key);
static inline _Bool
rb_ractor_main_p(void)
{
if (ruby_single_main_ractor) {
return 1;
}
else {
return rb_ractor_main_p_();
}
}
static inline _Bool
rb_ractor_status_p(rb_ractor_t *r, enum ractor_status status)
{
return r->status_ == status;
}
static inline void
rb_ractor_sleeper_threads_inc(rb_ractor_t *r)
{
r->threads.sleeper++;
}
static inline void
rb_ractor_sleeper_threads_dec(rb_ractor_t *r)
{
r->threads.sleeper--;
}
static inline void
rb_ractor_sleeper_threads_clear(rb_ractor_t *r)
{
r->threads.sleeper = 0;
}
static inline int
rb_ractor_sleeper_thread_num(rb_ractor_t *r)
{
return r->threads.sleeper;
}
static inline void
rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th)
{
if (cr->threads.running_ec != th->ec) {
if (0) {
ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n",
(void *)cr->threads.running_ec, (void *)th->ec);
}
}
else {
return;
}
if (cr->threads.running_ec != th->ec) {
th->running_time_us = 0;
}
cr->threads.running_ec = th->ec;
((void)0);
}
static inline void
rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const char *file, int line)
{
ruby_current_ec = ec;
;
((void)0);
cr->threads.running_ec = ec;
}
void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
static inline uint32_t
rb_ractor_id(const rb_ractor_t *r)
{
return r->pub.id;
}
_Bool rb_vm_locked_p(void);
void rb_vm_lock_body(void);
void rb_vm_unlock_body(void);
struct rb_ractor_struct;
void rb_vm_lock_enter_body_cr(struct rb_ractor_struct *cr, unsigned int *lev );
void rb_vm_lock_enter_body_nb(unsigned int *lev );
void rb_vm_lock_enter_body(unsigned int *lev );
void rb_vm_lock_leave_body(unsigned int *lev );
void rb_vm_barrier(void);
extern struct rb_ractor_struct *ruby_single_main_ractor;
static inline _Bool
rb_multi_ractor_p(void)
{
if ((__builtin_expect(!!(ruby_single_main_ractor), 1))) {
((void)0);
return 0;
}
else {
return 1;
}
}
static inline void
rb_vm_lock(const char *file, int line)
{
((void)0);
if (rb_multi_ractor_p()) {
rb_vm_lock_body();
}
}
static inline void
rb_vm_unlock(const char *file, int line)
{
if (rb_multi_ractor_p()) {
rb_vm_unlock_body();
}
}
static inline void
rb_vm_lock_enter(unsigned int *lev, const char *file, int line)
{
((void)0);
if (rb_multi_ractor_p()) {
rb_vm_lock_enter_body(lev );
}
}
static inline void
rb_vm_lock_enter_nb(unsigned int *lev, const char *file, int line)
{
((void)0);
if (rb_multi_ractor_p()) {
rb_vm_lock_enter_body_nb(lev );
}
}
static inline void
rb_vm_lock_leave(unsigned int *lev, const char *file, int line)
{
if (rb_multi_ractor_p()) {
rb_vm_lock_leave_body(lev );
}
}
static inline void
rb_vm_lock_enter_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char *file, int line)
{
((void)0);
rb_vm_lock_enter_body_cr(cr, levp );
}
static inline void
rb_vm_lock_leave_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char *file, int line)
{
rb_vm_lock_leave_body(levp );
}
struct rb_builtin_function {
const void * const func_ptr;
const int argc;
const int index;
const char * const name;
void (*compiler)(VALUE, long, unsigned, _Bool);
};
void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table);
typedef VALUE (*rb_builtin_arity0_function_type)(rb_execution_context_t *ec, VALUE self);
typedef VALUE (*rb_builtin_arity1_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE);
typedef VALUE (*rb_builtin_arity2_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE);
typedef VALUE (*rb_builtin_arity3_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity4_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity5_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity6_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity7_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity8_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity9_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity10_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity11_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity12_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity13_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity14_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
typedef VALUE (*rb_builtin_arity15_function_type)(rb_execution_context_t *ec, VALUE self,
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
static inline void rb_builtin_function_check_arity0(rb_builtin_arity0_function_type f){}
static inline void rb_builtin_function_check_arity1(rb_builtin_arity1_function_type f){}
static inline void rb_builtin_function_check_arity2(rb_builtin_arity2_function_type f){}
static inline void rb_builtin_function_check_arity3(rb_builtin_arity3_function_type f){}
static inline void rb_builtin_function_check_arity4(rb_builtin_arity4_function_type f){}
static inline void rb_builtin_function_check_arity5(rb_builtin_arity5_function_type f){}
static inline void rb_builtin_function_check_arity6(rb_builtin_arity6_function_type f){}
static inline void rb_builtin_function_check_arity7(rb_builtin_arity7_function_type f){}
static inline void rb_builtin_function_check_arity8(rb_builtin_arity8_function_type f){}
static inline void rb_builtin_function_check_arity9(rb_builtin_arity9_function_type f){}
static inline void rb_builtin_function_check_arity10(rb_builtin_arity10_function_type f){}
static inline void rb_builtin_function_check_arity11(rb_builtin_arity11_function_type f){}
static inline void rb_builtin_function_check_arity12(rb_builtin_arity12_function_type f){}
static inline void rb_builtin_function_check_arity13(rb_builtin_arity13_function_type f){}
static inline void rb_builtin_function_check_arity14(rb_builtin_arity14_function_type f){}
static inline void rb_builtin_function_check_arity15(rb_builtin_arity15_function_type f){}static inline
__attribute__((__pure__)) VALUE rb_vm_lvar_exposed(rb_execution_context_t *ec, int index);static inline
VALUE rb_vm_lvar_exposed(rb_execution_context_t *ec, int index);
__attribute__((__pure__)) static inline VALUE rb_vm_lvar(rb_execution_context_t *ec, int index);
static inline VALUE
rb_vm_lvar(rb_execution_context_t *ec, int index)
{
return ec->cfp->ep[index];
}
struct builtin_binary {
const char *feature;
const unsigned char *bin;
size_t bin_size;
};
struct ruby_dtrace_method_hook_args {
const char *classname;
const char *methodname;
const char *filename;
int line_no;
volatile VALUE klass;
volatile VALUE name;
};
__attribute__((__noinline__)) int rb_dtrace_setup(rb_execution_context_t *, VALUE, ID, struct ruby_dtrace_method_hook_args *);
VALUE rb_str_concat_literals(size_t, const VALUE*);
__attribute__ ((__visibility__("default"))) extern
VALUE rb_vm_exec(rb_execution_context_t *, _Bool);
extern const char *const rb_debug_counter_names[];
__attribute__((__pure__)) static inline const VALUE *VM_EP_LEP(const VALUE *);
static inline const VALUE *
VM_EP_LEP(const VALUE *ep)
{
while (!VM_ENV_LOCAL_P(ep)) {
ep = VM_ENV_PREV_EP(ep);
}
return ep;
}
static inline const rb_control_frame_t *
rb_vm_search_cf_from_ep(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE * const ep)
{
if (!ep) {
return ((void *)0);
}
else {
const rb_control_frame_t * const eocfp = RUBY_VM_END_CONTROL_FRAME(ec);
while (cfp < eocfp) {
if (cfp->ep == ep) {
return cfp;
}
cfp = ((cfp)+1);
}
return ((void *)0);
}
}static inline
const VALUE *
rb_vm_ep_local_ep(const VALUE *ep)
{
return VM_EP_LEP(ep);
}
__attribute__((__pure__)) static inline const VALUE *VM_CF_LEP(const rb_control_frame_t * const cfp);
static inline const VALUE *
VM_CF_LEP(const rb_control_frame_t * const cfp)
{
return VM_EP_LEP(cfp->ep);
}
static inline const VALUE *
VM_CF_PREV_EP(const rb_control_frame_t * const cfp)
{
return VM_ENV_PREV_EP(cfp->ep);
}
__attribute__((__pure__)) static inline VALUE VM_CF_BLOCK_HANDLER(const rb_control_frame_t * const cfp);
static inline VALUE
VM_CF_BLOCK_HANDLER(const rb_control_frame_t * const cfp)
{
const VALUE *ep = VM_CF_LEP(cfp);
return VM_ENV_BLOCK_HANDLER(ep);
}static inline
int
rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp)
{
return VM_FRAME_CFRAME_KW_P(cfp);
}static inline
VALUE
rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
{
return VM_CF_BLOCK_HANDLER(cfp);
}
static struct rb_captured_block *
VM_CFP_TO_CAPTURED_BLOCK(const rb_control_frame_t *cfp)
{
((void)0);
return (struct rb_captured_block *)&cfp->self;
}
static rb_control_frame_t *
VM_CAPTURED_BLOCK_TO_CFP(const struct rb_captured_block *captured)
{
rb_control_frame_t *cfp = ((rb_control_frame_t *)((VALUE *)(captured) - 3));
((void)0);
((void)0);
return cfp;
}
static int
VM_BH_FROM_CFP_P(VALUE block_handler, const rb_control_frame_t *cfp)
{
const struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
return ((void *)((block_handler) & ~0x03)) == captured;
}
static VALUE
vm_passed_block_handler(rb_execution_context_t *ec)
{
VALUE block_handler = ec->passed_block_handler;
ec->passed_block_handler = 0;
vm_block_handler_verify(block_handler);
return block_handler;
}
static rb_cref_t *
vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int use_prev_prev, int singleton)
{
VALUE refinements = ((VALUE)RUBY_Qnil);
int omod_shared = 0;
rb_cref_t *cref;
union {
rb_scope_visibility_t visi;
VALUE value;
} scope_visi;
scope_visi.visi.method_visi = visi;
scope_visi.visi.module_func = module_func;
if (prev_cref != ((void *)0) && prev_cref != (void *)1 ) {
refinements = CREF_REFINEMENTS(prev_cref);
if (!RB_NIL_P(refinements)) {
omod_shared = 1;
CREF_OMOD_SHARED_SET(prev_cref);
}
}
((void)0);
cref = (rb_cref_t *)rb_imemo_new(imemo_cref, klass, (VALUE)(use_prev_prev ? CREF_NEXT(prev_cref) : prev_cref), scope_visi.value, refinements);
if (pushed_by_eval) CREF_PUSHED_BY_EVAL_SET(cref);
if (omod_shared) CREF_OMOD_SHARED_SET(cref);
if (singleton) CREF_SINGLETON_SET(cref);
return cref;
}
static rb_cref_t *
vm_cref_new(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int singleton)
{
return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, 0, singleton);
}
static rb_cref_t *
vm_cref_new_use_prev(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
{
return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, 1, 0);
}
static int
ref_delete_symkey(VALUE key, VALUE value, VALUE unused)
{
return RB_SYMBOL_P(key) ? ST_DELETE : ST_CONTINUE;
}
static rb_cref_t *
vm_cref_dup(const rb_cref_t *cref)
{
const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
rb_cref_t *next_cref = CREF_NEXT(cref), *new_cref;
int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
int singleton = CREF_SINGLETON(cref);
new_cref = vm_cref_new(cref->klass_or_self, visi->method_visi, visi->module_func, next_cref, pushed_by_eval, singleton);
if (!RB_NIL_P(CREF_REFINEMENTS(cref))) {
VALUE ref = rb_hash_dup(CREF_REFINEMENTS(cref));
rb_hash_foreach(ref, ref_delete_symkey, ((VALUE)RUBY_Qnil));
CREF_REFINEMENTS_SET(new_cref, ref);
CREF_OMOD_SHARED_UNSET(new_cref);
}
return new_cref;
}static inline
rb_cref_t *
rb_vm_cref_dup_without_refinements(const rb_cref_t *cref)
{
const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
rb_cref_t *next_cref = CREF_NEXT(cref), *new_cref;
int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
int singleton = CREF_SINGLETON(cref);
new_cref = vm_cref_new(cref->klass_or_self, visi->method_visi, visi->module_func, next_cref, pushed_by_eval, singleton);
if (!RB_NIL_P(CREF_REFINEMENTS(cref))) {
CREF_REFINEMENTS_SET(new_cref, ((VALUE)RUBY_Qnil));
CREF_OMOD_SHARED_UNSET(new_cref);
}
return new_cref;
}
static rb_cref_t *
vm_cref_new_toplevel(rb_execution_context_t *ec)
{
rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE , 0, ((void *)0), 0, 0);
VALUE top_wrapper = rb_ec_thread_ptr(ec)->top_wrapper;
if (top_wrapper) {
cref = vm_cref_new(top_wrapper, METHOD_VISI_PRIVATE, 0, cref, 0, 0);
}
return cref;
}static inline
rb_cref_t *
rb_vm_cref_new_toplevel(void)
{
return vm_cref_new_toplevel(rb_current_execution_context(1));
}
static void
vm_cref_dump(const char *mesg, const rb_cref_t *cref)
{
ruby_debug_printf("vm_cref_dump: %s (%p)\n", mesg, (void *)cref);
while (cref) {
ruby_debug_printf("= cref| klass: %s\n", RSTRING_PTR(rb_class_path(CREF_CLASS(cref))));
cref = CREF_NEXT(cref);
}
}static inline
void
rb_vm_block_ep_update(VALUE obj, const struct rb_block *dst, const VALUE *ep)
{
*((const VALUE **)&dst->as.captured.ep) = ep;
(rb_obj_written((VALUE)(obj), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(VM_ENV_ENVVAL(ep)), "./vm.c", 360));
}
static void
vm_bind_update_env(VALUE bindval, rb_binding_t *bind, VALUE envval)
{
const rb_env_t *env = (rb_env_t *)envval;
rb_obj_write((VALUE)(bindval), ((VALUE *)(&bind->block.as.captured.code.iseq)), (VALUE)(env->iseq), "./vm.c", 367);
rb_vm_block_ep_update(bindval, &bind->block, env->ep);
}
static VALUE vm_make_env_object(const rb_execution_context_t *ec, rb_control_frame_t *cfp);
extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
int argc, const VALUE *argv, int kw_splat, VALUE block_handler,
const rb_callable_method_entry_t *me);
static VALUE vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, int kw_splat, VALUE block_handler);
__attribute__((__noinline__)) static __attribute__((__cold__)) VALUE mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body);
static VALUE
mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
{
uintptr_t mjit_state = (uintptr_t)(body->jit_func);
((__builtin_expect(!!(!!(((uintptr_t)(mjit_state) <= (uintptr_t)MJIT_FUNC_FAILED))), 1)) ? ((void)0) : __builtin_unreachable());
switch ((enum rb_mjit_func_state)mjit_state) {
case MJIT_FUNC_NOT_COMPILED:
if (body->total_calls == mjit_opts.call_threshold) {
rb_mjit_add_iseq_to_process(iseq);
if ((__builtin_expect(!!(mjit_opts.wait && !((uintptr_t)(body->jit_func) <= (uintptr_t)MJIT_FUNC_FAILED)), 0))) {
return body->jit_func(ec, ec->cfp);
}
}
break;
case MJIT_FUNC_COMPILING:
case MJIT_FUNC_FAILED:
break;
}
return ((VALUE)RUBY_Qundef);
}
static inline VALUE
jit_exec(rb_execution_context_t *ec)
{
const rb_iseq_t *iseq = ec->cfp->iseq;
struct rb_iseq_constant_body *body = ((iseq)->body);
_Bool yjit_enabled = rb_yjit_enabled_p();
if (yjit_enabled || mjit_call_p) {
body->total_calls++;
}
else {
return ((VALUE)RUBY_Qundef);
}
jit_func_t func;
if (yjit_enabled) {
if (body->total_calls == rb_yjit_call_threshold()) {
if (!rb_yjit_compile_iseq(iseq, ec)) {
return ((VALUE)RUBY_Qundef);
}
}
if ((func = body->jit_func) == 0) {
return ((VALUE)RUBY_Qundef);
}
}
else if ((__builtin_expect(!!(((uintptr_t)(func = body->jit_func) <= (uintptr_t)MJIT_FUNC_FAILED)), 0))) {
return mjit_check_iseq(ec, iseq, body);
}
return func(ec, ec->cfp);
}
typedef enum
{
memory_order_relaxed = 0,
memory_order_consume = 1,
memory_order_acquire = 2,
memory_order_release = 3,
memory_order_acq_rel = 4,
memory_order_seq_cst = 5
} memory_order;
typedef _Atomic _Bool atomic_bool;
typedef _Atomic char atomic_char;
typedef _Atomic signed char atomic_schar;
typedef _Atomic unsigned char atomic_uchar;
typedef _Atomic short atomic_short;
typedef _Atomic unsigned short atomic_ushort;
typedef _Atomic int atomic_int;
typedef _Atomic unsigned int atomic_uint;
typedef _Atomic long atomic_long;
typedef _Atomic unsigned long atomic_ulong;
typedef _Atomic long long atomic_llong;
typedef _Atomic unsigned long long atomic_ullong;
typedef _Atomic short unsigned int atomic_char16_t;
typedef _Atomic unsigned int atomic_char32_t;
typedef _Atomic int atomic_wchar_t;
typedef _Atomic signed char atomic_int_least8_t;
typedef _Atomic unsigned char atomic_uint_least8_t;
typedef _Atomic short int atomic_int_least16_t;
typedef _Atomic short unsigned int atomic_uint_least16_t;
typedef _Atomic int atomic_int_least32_t;
typedef _Atomic unsigned int atomic_uint_least32_t;
typedef _Atomic long int atomic_int_least64_t;
typedef _Atomic long unsigned int atomic_uint_least64_t;
typedef _Atomic signed char atomic_int_fast8_t;
typedef _Atomic unsigned char atomic_uint_fast8_t;
typedef _Atomic long int atomic_int_fast16_t;
typedef _Atomic long unsigned int atomic_uint_fast16_t;
typedef _Atomic long int atomic_int_fast32_t;
typedef _Atomic long unsigned int atomic_uint_fast32_t;
typedef _Atomic long int atomic_int_fast64_t;
typedef _Atomic long unsigned int atomic_uint_fast64_t;
typedef _Atomic long int atomic_intptr_t;
typedef _Atomic long unsigned int atomic_uintptr_t;
typedef _Atomic long unsigned int atomic_size_t;
typedef _Atomic long int atomic_ptrdiff_t;
typedef _Atomic long int atomic_intmax_t;
typedef _Atomic long unsigned int atomic_uintmax_t;
extern void atomic_thread_fence (memory_order);
extern void atomic_signal_fence (memory_order);
typedef _Atomic struct
{
_Bool __val;
} atomic_flag;
extern _Bool atomic_flag_test_and_set (volatile atomic_flag *);
extern _Bool atomic_flag_test_and_set_explicit (volatile atomic_flag *,
memory_order);
extern void atomic_flag_clear (volatile atomic_flag *);
extern void atomic_flag_clear_explicit (volatile atomic_flag *, memory_order);
VALUE rb_invcmp(VALUE, VALUE);
struct ar_table_struct;
typedef unsigned char ar_hint_t;
enum ruby_rhash_flags {
RHASH_PASS_AS_KEYWORDS = ((VALUE)RUBY_FL_USER1),
RHASH_PROC_DEFAULT = ((VALUE)RUBY_FL_USER2),
RHASH_ST_TABLE_FLAG = ((VALUE)RUBY_FL_USER3),
RHASH_AR_TABLE_SIZE_MASK = (((VALUE)RUBY_FL_USER4)|((VALUE)RUBY_FL_USER5)|((VALUE)RUBY_FL_USER6)|((VALUE)RUBY_FL_USER7)),
RHASH_AR_TABLE_SIZE_SHIFT = (((VALUE)RUBY_FL_USHIFT)+4),
RHASH_AR_TABLE_BOUND_MASK = (((VALUE)RUBY_FL_USER8)|((VALUE)RUBY_FL_USER9)|((VALUE)RUBY_FL_USER10)|((VALUE)RUBY_FL_USER11)),
RHASH_AR_TABLE_BOUND_SHIFT = (((VALUE)RUBY_FL_USHIFT)+8),
RHASH_TRANSIENT_FLAG = ((VALUE)RUBY_FL_USER12),
RHASH_LEV_SHIFT = (((VALUE)RUBY_FL_USHIFT) + 13),
RHASH_LEV_MAX = 127,
};
struct RHash {
struct RBasic basic;
union {
st_table *st;
struct ar_table_struct *ar;
} as;
const VALUE ifnone;
union {
ar_hint_t ary[8];
VALUE word;
} ar_hint;
};
void rb_hash_st_table_set(VALUE hash, st_table *st);
VALUE rb_hash_default_value(VALUE hash, VALUE key);
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
long rb_dbl_long_hash(double d);
st_table *rb_init_identtable(void);
st_index_t rb_any_hash(VALUE a);
VALUE rb_to_hash_type(VALUE obj);
VALUE rb_hash_key_str(VALUE);
VALUE rb_hash_values(VALUE hash);
VALUE rb_hash_rehash(VALUE hash);
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
extern st_table *rb_hash_st_table(VALUE hash);
VALUE rb_ident_hash_new_with_size(st_index_t size);
static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
static inline VALUE RHASH_IFNONE(VALUE h);
static inline size_t RHASH_SIZE(VALUE h);
static inline _Bool RHASH_EMPTY_P(VALUE h);
static inline _Bool RHASH_AR_TABLE_P(VALUE h);
static inline _Bool RHASH_ST_TABLE_P(VALUE h);
static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
static inline st_table *RHASH_ST_TABLE(VALUE h);
static inline size_t RHASH_ST_SIZE(VALUE h);
static inline void RHASH_ST_CLEAR(VALUE h);
static inline _Bool RHASH_TRANSIENT_P(VALUE h);
static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
VALUE rb_ident_hash_new(void);
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
VALUE rb_hash_new_with_size(st_index_t size);
VALUE rb_hash_resurrect(VALUE hash);
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
VALUE rb_hash_keys(VALUE hash);
VALUE rb_hash_has_key(VALUE hash, VALUE key);
VALUE rb_hash_compare_by_id_p(VALUE hash);
st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
VALUE rb_hash_compare_by_id(VALUE hash);
static inline _Bool
RHASH_AR_TABLE_P(VALUE h)
{
return ! RB_FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
}
static inline struct ar_table_struct *
RHASH_AR_TABLE(VALUE h)
{
return ((struct RHash *)(h))->as.ar;
}
static inline st_table *
RHASH_ST_TABLE(VALUE h)
{
return ((struct RHash *)(h))->as.st;
}
static inline VALUE
RHASH_IFNONE(VALUE h)
{
return ((struct RHash *)(h))->ifnone;
}
static inline size_t
RHASH_SIZE(VALUE h)
{
if (RHASH_AR_TABLE_P(h)) {
return RHASH_AR_TABLE_SIZE_RAW(h);
}
else {
return RHASH_ST_SIZE(h);
}
}
static inline _Bool
RHASH_EMPTY_P(VALUE h)
{
return RHASH_SIZE(h) == 0;
}
static inline _Bool
RHASH_ST_TABLE_P(VALUE h)
{
return ! RHASH_AR_TABLE_P(h);
}
static inline size_t
RHASH_ST_SIZE(VALUE h)
{
return RHASH_ST_TABLE(h)->num_entries;
}
static inline void
RHASH_ST_CLEAR(VALUE h)
{
RB_FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
((struct RHash *)(h))->as.ar = ((void *)0);
}
static inline unsigned
RHASH_AR_TABLE_SIZE_RAW(VALUE h)
{
VALUE ret = RB_FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
return (unsigned)ret;
}
static inline _Bool
RHASH_TRANSIENT_P(VALUE h)
{
return RB_FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
}
static inline void
RHASH_SET_TRANSIENT_FLAG(VALUE h)
{
RB_FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
}
static inline void
RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
{
RB_FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
}
enum rb_int_parse_flags {
RB_INT_PARSE_SIGN = 0x01,
RB_INT_PARSE_UNDERSCORE = 0x02,
RB_INT_PARSE_PREFIX = 0x04,
RB_INT_PARSE_ALL = 0x07,
RB_INT_PARSE_DEFAULT = 0x07,
};
struct RBignum {
struct RBasic basic;
union {
struct {
size_t len;
unsigned int *digits;
} heap;
unsigned int ary[(8*3/4)];
} as;
};
extern const char ruby_digitmap[];
double rb_big_fdiv_double(VALUE x, VALUE y);
VALUE rb_big_uminus(VALUE x);
VALUE rb_big_hash(VALUE);
VALUE rb_big_odd_p(VALUE);
VALUE rb_big_even_p(VALUE);
size_t rb_big_size(VALUE);
VALUE rb_integer_float_cmp(VALUE x, VALUE y);
VALUE rb_integer_float_eq(VALUE x, VALUE y);
VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
VALUE rb_big_comp(VALUE x);
VALUE rb_big_aref(VALUE x, VALUE y);
VALUE rb_big_abs(VALUE x);
VALUE rb_big_size_m(VALUE big);
VALUE rb_big_bit_length(VALUE big);
VALUE rb_big_remainder(VALUE x, VALUE y);
VALUE rb_big_gt(VALUE x, VALUE y);
VALUE rb_big_ge(VALUE x, VALUE y);
VALUE rb_big_lt(VALUE x, VALUE y);
VALUE rb_big_le(VALUE x, VALUE y);
VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
VALUE rb_big_isqrt(VALUE n);
static inline _Bool BIGNUM_SIGN(VALUE b);
static inline _Bool BIGNUM_POSITIVE_P(VALUE b);
static inline _Bool BIGNUM_NEGATIVE_P(VALUE b);
static inline void BIGNUM_SET_SIGN(VALUE b, _Bool sign);
static inline void BIGNUM_NEGATE(VALUE b);
static inline size_t BIGNUM_LEN(VALUE b);
static inline unsigned int *BIGNUM_DIGITS(VALUE b);
static inline int BIGNUM_LENINT(VALUE b);
static inline _Bool BIGNUM_EMBED_P(VALUE b);
VALUE rb_big_mul_normal(VALUE x, VALUE y);
VALUE rb_big_mul_balance(VALUE x, VALUE y);
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
VALUE rb_big_mul_toom3(VALUE x, VALUE y);
VALUE rb_big_sq_fast(VALUE x);
VALUE rb_big_divrem_normal(VALUE x, VALUE y);
VALUE rb_big2str_poweroftwo(VALUE x, int base);
VALUE rb_big2str_generic(VALUE x, int base);
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
VALUE rb_big_mul_gmp(VALUE x, VALUE y);
VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
VALUE rb_big2str_gmp(VALUE x, int base);
VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
VALUE rb_int128t2big(__int128 n);
static inline _Bool
BIGNUM_SIGN(VALUE b)
{
return RB_FL_TEST_RAW(b, ((VALUE)RUBY_FL_USER1));
}
static inline _Bool
BIGNUM_POSITIVE_P(VALUE b)
{
return BIGNUM_SIGN(b);
}
static inline _Bool
BIGNUM_NEGATIVE_P(VALUE b)
{
return ! BIGNUM_POSITIVE_P(b);
}
static inline void
BIGNUM_SET_SIGN(VALUE b, _Bool sign)
{
if (sign) {
RB_FL_SET_RAW(b, ((VALUE)RUBY_FL_USER1));
}
else {
RB_FL_UNSET_RAW(b, ((VALUE)RUBY_FL_USER1));
}
}
static inline void
BIGNUM_NEGATE(VALUE b)
{
RB_FL_REVERSE_RAW(b, ((VALUE)RUBY_FL_USER1));
}
static inline size_t
BIGNUM_LEN(VALUE b)
{
if (! BIGNUM_EMBED_P(b)) {
return ((struct RBignum *)(b))->as.heap.len;
}
else {
size_t ret = ((struct RBasic *)(b))->flags;
ret &= (~(~(VALUE)0U << 3) << (((VALUE)RUBY_FL_USHIFT)+3));
ret >>= (((VALUE)RUBY_FL_USHIFT)+3);
return ret;
}
}
static inline int
BIGNUM_LENINT(VALUE b)
{
return rb_long2int_inline(BIGNUM_LEN(b));
}
static inline unsigned int *
BIGNUM_DIGITS(VALUE b)
{
if (BIGNUM_EMBED_P(b)) {
return ((struct RBignum *)(b))->as.ary;
}
else {
return ((struct RBignum *)(b))->as.heap.digits;
}
}
static inline _Bool
BIGNUM_EMBED_P(VALUE b)
{
return RB_FL_TEST_RAW(b, ((VALUE)((VALUE)RUBY_FL_USER2)));
}
static inline uint16_t ruby_swap16(uint16_t);
static inline uint32_t ruby_swap32(uint32_t);
static inline uint64_t ruby_swap64(uint64_t);
static inline unsigned nlz_int(unsigned x);
static inline unsigned nlz_long(unsigned long x);
static inline unsigned nlz_long_long(unsigned long long x);
static inline unsigned nlz_intptr(uintptr_t x);
static inline unsigned nlz_int32(uint32_t x);
static inline unsigned nlz_int64(uint64_t x);
static inline unsigned nlz_int128(unsigned __int128 x);
static inline unsigned rb_popcount32(uint32_t x);
static inline unsigned rb_popcount64(uint64_t x);
static inline unsigned rb_popcount_intptr(uintptr_t x);
static inline int ntz_int32(uint32_t x);
static inline int ntz_int64(uint64_t x);
static inline int ntz_intptr(uintptr_t x);
static inline VALUE RUBY_BIT_ROTL(VALUE, int);
static inline VALUE RUBY_BIT_ROTR(VALUE, int);
static inline uint16_t
ruby_swap16(uint16_t x)
{
return __builtin_bswap16(x);
}
static inline uint32_t
ruby_swap32(uint32_t x)
{
return __builtin_bswap32(x);
}
static inline uint64_t
ruby_swap64(uint64_t x)
{
return __builtin_bswap64(x);
}
static inline unsigned int
nlz_int32(uint32_t x)
{
__extension__ _Static_assert(sizeof(int) * 8 == 32, "sizeof_int" ": " "sizeof(int) * CHAR_BIT == 32");
return x ? (unsigned int)__builtin_clz(x) : 32;
}
static inline unsigned int
nlz_int64(uint64_t x)
{
if (x == 0) {
return 64;
}
else if (sizeof(long) * 8 == 64) {
return (unsigned int)__builtin_clzl((unsigned long)x);
}
else if (sizeof(long long) * 8 == 64) {
return (unsigned int)__builtin_clzll((unsigned long long)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
nlz_int128(unsigned __int128 x)
{
uint64_t y = (uint64_t)(x >> 64);
if (x == 0) {
return 128;
}
else if (y == 0) {
return (unsigned int)nlz_int64(x) + 64;
}
else {
return (unsigned int)nlz_int64(y);
}
}
static inline unsigned int
nlz_int(unsigned int x)
{
if (sizeof(unsigned int) * 8 == 32) {
return nlz_int32((uint32_t)x);
}
else if (sizeof(unsigned int) * 8 == 64) {
return nlz_int64((uint64_t)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
nlz_long(unsigned long x)
{
if (sizeof(unsigned long) * 8 == 32) {
return nlz_int32((uint32_t)x);
}
else if (sizeof(unsigned long) * 8 == 64) {
return nlz_int64((uint64_t)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
nlz_long_long(unsigned long long x)
{
if (sizeof(unsigned long long) * 8 == 64) {
return nlz_int64((uint64_t)x);
}
else if (sizeof(unsigned long long) * 8 == 128) {
return nlz_int128((unsigned __int128)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
nlz_intptr(uintptr_t x)
{
if (sizeof(uintptr_t) == sizeof(unsigned int)) {
return nlz_int((unsigned int)x);
}
if (sizeof(uintptr_t) == sizeof(unsigned long)) {
return nlz_long((unsigned long)x);
}
if (sizeof(uintptr_t) == sizeof(unsigned long long)) {
return nlz_long_long((unsigned long long)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
rb_popcount32(uint32_t x)
{
__extension__ _Static_assert(sizeof(int) * 8 >= 32, "sizeof_int" ": " "sizeof(int) * CHAR_BIT >= 32");
return (unsigned int)__builtin_popcount(x);
}
static inline unsigned int
rb_popcount64(uint64_t x)
{
if (sizeof(long) * 8 == 64) {
return (unsigned int)__builtin_popcountl((unsigned long)x);
}
else if (sizeof(long long) * 8 == 64) {
return (unsigned int)__builtin_popcountll((unsigned long long)x);
}
else {
__builtin_unreachable();
}
}
static inline unsigned int
rb_popcount_intptr(uintptr_t x)
{
if (sizeof(uintptr_t) * 8 == 64) {
return rb_popcount64((uint64_t)x);
}
else if (sizeof(uintptr_t) * 8 == 32) {
return rb_popcount32((uint32_t)x);
}
else {
__builtin_unreachable();
}
}
static inline int
ntz_int32(uint32_t x)
{
__extension__ _Static_assert(sizeof(int) * 8 == 32, "sizeof_int" ": " "sizeof(int) * CHAR_BIT == 32");
return x ? (unsigned)__builtin_ctz(x) : 32;
}
static inline int
ntz_int64(uint64_t x)
{
if (x == 0) {
return 64;
}
else if (sizeof(long) * 8 == 64) {
return (unsigned)__builtin_ctzl((unsigned long)x);
}
else if (sizeof(long long) * 8 == 64) {
return (unsigned)__builtin_ctzll((unsigned long long)x);
}
else {
__builtin_unreachable();
}
}
static inline int
ntz_intptr(uintptr_t x)
{
if (sizeof(uintptr_t) * 8 == 64) {
return ntz_int64((uint64_t)x);
}
else if (sizeof(uintptr_t) * 8 == 32) {
return ntz_int32((uint32_t)x);
}
else {
__builtin_unreachable();
}
}
static inline VALUE
RUBY_BIT_ROTL(VALUE v, int n)
{
const int m = (sizeof(VALUE) * 8) - 1;
return (v << (n & m)) | (v >> (-n & m));
}
static inline VALUE
RUBY_BIT_ROTR(VALUE v, int n)
{
const int m = (sizeof(VALUE) * 8) - 1;
return (v << (-n & m)) | (v >> (n & m));
}
VALUE rb_int128t2big(__int128 n);
static inline long rb_overflowed_fix_to_int(long x);
static inline VALUE rb_fix_plus_fix(VALUE x, VALUE y);
static inline VALUE rb_fix_minus_fix(VALUE x, VALUE y);
static inline VALUE rb_fix_mul_fix(VALUE x, VALUE y);
static inline void rb_fix_divmod_fix(VALUE x, VALUE y, VALUE *divp, VALUE *modp);
static inline VALUE rb_fix_div_fix(VALUE x, VALUE y);
static inline VALUE rb_fix_mod_fix(VALUE x, VALUE y);
static inline _Bool FIXNUM_POSITIVE_P(VALUE num);
static inline _Bool FIXNUM_NEGATIVE_P(VALUE num);
static inline _Bool FIXNUM_ZERO_P(VALUE num);
static inline long
rb_overflowed_fix_to_int(long x)
{
return (long)((unsigned long)(x >> 1) ^ (1LU << (8 * 8 - 1)));
}
static inline VALUE
rb_fix_plus_fix(VALUE x, VALUE y)
{
long lz;
if (__builtin_add_overflow((long)x, (long)y-1, &lz)) {
return rb_int2big(rb_overflowed_fix_to_int(lz));
}
else {
return (VALUE)lz;
}
}
static inline VALUE
rb_fix_minus_fix(VALUE x, VALUE y)
{
long lz;
if (__builtin_sub_overflow((long)x, (long)y-1, &lz)) {
return rb_int2big(rb_overflowed_fix_to_int(lz));
}
else {
return (VALUE)lz;
}
}
static inline VALUE
rb_fix_mul_fix(VALUE x, VALUE y)
{
long lx = rb_fix2long(x);
long ly = rb_fix2long(y);
return (((((__int128)lx * (__int128)ly) < (0x7fffffffffffffffL / 2) + 1) && (((__int128)lx * (__int128)ly) >= ((-0x7fffffffffffffffL - 1L) / 2))) ? RB_INT2FIX((__int128)lx * (__int128)ly) : rb_int128t2big((__int128)lx * (__int128)ly));
}
static inline void
rb_fix_divmod_fix(VALUE a, VALUE b, VALUE *divp, VALUE *modp)
{
long x = rb_fix2long(a);
long y = rb_fix2long(b);
long div, mod;
if (x == ((-0x7fffffffffffffffL - 1L) / 2) && y == -1) {
if (divp) *divp = rb_long2num_inline(-((-0x7fffffffffffffffL - 1L) / 2));
if (modp) *modp = RB_INT2FIX(0);
return;
}
div = x / y;
mod = x % y;
if (y > 0 ? mod < 0 : mod > 0) {
mod += y;
div -= 1;
}
if (divp) *divp = RB_INT2FIX(div);
if (modp) *modp = RB_INT2FIX(mod);
}
static inline VALUE
rb_fix_div_fix(VALUE x, VALUE y)
{
VALUE div;
rb_fix_divmod_fix(x, y, &div, ((void *)0));
return div;
}
static inline VALUE
rb_fix_mod_fix(VALUE x, VALUE y)
{
VALUE mod;
rb_fix_divmod_fix(x, y, ((void *)0), &mod);
return mod;
}
static inline _Bool
FIXNUM_POSITIVE_P(VALUE num)
{
return (long)num > (long)__builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0));
}
static inline _Bool
FIXNUM_NEGATIVE_P(VALUE num)
{
return (long)num < 0;
}
static inline _Bool
FIXNUM_ZERO_P(VALUE num)
{
return num == __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0));
}
enum ruby_num_rounding_mode {
RUBY_NUM_ROUND_HALF_UP,
RUBY_NUM_ROUND_HALF_EVEN,
RUBY_NUM_ROUND_HALF_DOWN,
RUBY_NUM_ROUND_DEFAULT = RUBY_NUM_ROUND_HALF_UP,
};
typedef double rb_float_value_type;
struct RFloat {
struct RBasic basic;
rb_float_value_type float_value;
};
int rb_num_to_uint(VALUE val, unsigned int *ret);
VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
double ruby_float_step_size(double beg, double end, double unit, int excl);
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
int rb_num_negative_p(VALUE);
VALUE rb_int_succ(VALUE num);
VALUE rb_float_uminus(VALUE num);
VALUE rb_int_plus(VALUE x, VALUE y);
VALUE rb_float_plus(VALUE x, VALUE y);
VALUE rb_int_minus(VALUE x, VALUE y);
VALUE rb_float_minus(VALUE x, VALUE y);
VALUE rb_int_mul(VALUE x, VALUE y);
VALUE rb_float_mul(VALUE x, VALUE y);
VALUE rb_float_div(VALUE x, VALUE y);
VALUE rb_int_idiv(VALUE x, VALUE y);
VALUE rb_int_modulo(VALUE x, VALUE y);
VALUE rb_int2str(VALUE num, int base);
VALUE rb_fix_plus(VALUE x, VALUE y);
VALUE rb_int_gt(VALUE x, VALUE y);
VALUE rb_float_gt(VALUE x, VALUE y);
VALUE rb_int_ge(VALUE x, VALUE y);
enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
double rb_int_fdiv_double(VALUE x, VALUE y);
VALUE rb_int_pow(VALUE x, VALUE y);
VALUE rb_float_pow(VALUE x, VALUE y);
VALUE rb_int_cmp(VALUE x, VALUE y);
VALUE rb_int_equal(VALUE x, VALUE y);
VALUE rb_int_divmod(VALUE x, VALUE y);
VALUE rb_int_and(VALUE x, VALUE y);
VALUE rb_int_lshift(VALUE x, VALUE y);
VALUE rb_int_div(VALUE x, VALUE y);
int rb_int_positive_p(VALUE num);
int rb_int_negative_p(VALUE num);
VALUE rb_check_integer_type(VALUE);
VALUE rb_num_pow(VALUE x, VALUE y);
VALUE rb_float_ceil(VALUE num, int ndigits);
VALUE rb_float_floor(VALUE x, int ndigits);
VALUE rb_float_abs(VALUE flt);
static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
static inline int rb_num_positive_int_p(VALUE num);
static inline int rb_num_negative_int_p(VALUE num);
static inline double rb_float_flonum_value(VALUE v);
static inline double rb_float_noflonum_value(VALUE v);
static inline double rb_float_value_inline(VALUE v);
static inline VALUE rb_float_new_inline(double d);
static inline _Bool INT_POSITIVE_P(VALUE num);
static inline _Bool INT_NEGATIVE_P(VALUE num);
static inline _Bool FLOAT_ZERO_P(VALUE num);
VALUE rb_flo_div_flo(VALUE x, VALUE y);
double ruby_float_mod(double x, double y);
VALUE rb_float_equal(VALUE x, VALUE y);
int rb_float_cmp(VALUE x, VALUE y);
VALUE rb_float_eql(VALUE x, VALUE y);
VALUE rb_fix_aref(VALUE fix, VALUE idx);
VALUE rb_int_zero_p(VALUE num);
VALUE rb_int_even_p(VALUE num);
VALUE rb_int_odd_p(VALUE num);
VALUE rb_int_abs(VALUE num);
VALUE rb_int_bit_length(VALUE num);
VALUE rb_int_uminus(VALUE num);
VALUE rb_int_comp(VALUE num);
static inline _Bool
INT_POSITIVE_P(VALUE num)
{
if (RB_FIXNUM_P(num)) {
return FIXNUM_POSITIVE_P(num);
}
else {
return BIGNUM_POSITIVE_P(num);
}
}
static inline _Bool
INT_NEGATIVE_P(VALUE num)
{
if (RB_FIXNUM_P(num)) {
return FIXNUM_NEGATIVE_P(num);
}
else {
return BIGNUM_NEGATIVE_P(num);
}
}
static inline _Bool
FLOAT_ZERO_P(VALUE num)
{
return rb_float_value_inline(num) == 0.0;
}
static inline VALUE
rb_num_compare_with_zero(VALUE num, ID mid)
{
VALUE zero = __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0));
VALUE r = rb_check_funcall(num, mid, 1, &zero);
if (r == ((VALUE)RUBY_Qundef)) {
rb_cmperr(num, zero);
}
return r;
}
static inline int
rb_num_positive_int_p(VALUE num)
{
const ID mid = '>';
if (RB_FIXNUM_P(num)) {
if (rb_method_basic_definition_p(rb_cInteger, mid))
return FIXNUM_POSITIVE_P(num);
}
else if (RB_TYPE_P(num, RUBY_T_BIGNUM)) {
if (rb_method_basic_definition_p(rb_cInteger, mid))
return BIGNUM_POSITIVE_P(num);
}
return RB_TEST(rb_num_compare_with_zero(num, mid));
}
static inline int
rb_num_negative_int_p(VALUE num)
{
const ID mid = '<';
if (RB_FIXNUM_P(num)) {
if (rb_method_basic_definition_p(rb_cInteger, mid))
return FIXNUM_NEGATIVE_P(num);
}
else if (RB_TYPE_P(num, RUBY_T_BIGNUM)) {
if (rb_method_basic_definition_p(rb_cInteger, mid))
return BIGNUM_NEGATIVE_P(num);
}
return RB_TEST(rb_num_compare_with_zero(num, mid));
}
static inline double
rb_float_flonum_value(VALUE v)
{
if (v != (VALUE)0x8000000000000002) {
union {
double d;
VALUE v;
} t;
VALUE b63 = (v >> 63);
t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
return t.d;
}
return 0.0;
}
static inline double
rb_float_noflonum_value(VALUE v)
{
return ((struct RFloat *)(v))->float_value;
}
static inline double
rb_float_value_inline(VALUE v)
{
if (RB_FLONUM_P(v)) {
return rb_float_flonum_value(v);
}
return rb_float_noflonum_value(v);
}
static inline VALUE
rb_float_new_inline(double d)
{
union {
double d;
VALUE v;
} t;
int bits;
t.d = d;
bits = (int)((VALUE)(t.v >> 60) & 0x7);
if (t.v != 0x3000000000000000 &&
!((bits-3) & ~0x01)) {
return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
}
else if (t.v == (VALUE)0) {
return 0x8000000000000002;
}
return rb_float_new_in_heap(d);
}
int ruby_fill_random_bytes(void *, size_t, int);
enum {
RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
RSTRUCT_TRANSIENT_FLAG = ((VALUE)RUBY_FL_USER3),
};
struct RStruct {
struct RBasic basic;
union {
struct {
long len;
const VALUE *ptr;
} heap;
const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
} as;
};
VALUE rb_struct_init_copy(VALUE copy, VALUE s);
VALUE rb_struct_lookup(VALUE s, VALUE idx);
VALUE rb_struct_s_keyword_init(VALUE klass);
static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
static inline _Bool RSTRUCT_TRANSIENT_P(VALUE st);
static inline void RSTRUCT_TRANSIENT_SET(VALUE st);
static inline void RSTRUCT_TRANSIENT_UNSET(VALUE st);
static inline long RSTRUCT_EMBED_LEN(VALUE st);
static inline long internal_RSTRUCT_LEN(VALUE st);
static inline int RSTRUCT_LENINT(VALUE st);
static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
static inline void internal_RSTRUCT_SET(VALUE st, long k, VALUE v);
static inline VALUE internal_RSTRUCT_GET(VALUE st, long k);
static inline _Bool
RSTRUCT_TRANSIENT_P(VALUE st)
{
return RB_FL_TEST_RAW(st, RSTRUCT_TRANSIENT_FLAG);
}
static inline void
RSTRUCT_TRANSIENT_SET(VALUE st)
{
RB_FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
}
static inline void
RSTRUCT_TRANSIENT_UNSET(VALUE st)
{
RB_FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
}
static inline long
RSTRUCT_EMBED_LEN(VALUE st)
{
long ret = RB_FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK);
ret >>= RSTRUCT_EMBED_LEN_SHIFT;
return ret;
}
static inline long
internal_RSTRUCT_LEN(VALUE st)
{
if (RB_FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
return RSTRUCT_EMBED_LEN(st);
}
else {
return ((struct RStruct *)(st))->as.heap.len;
}
}
static inline int
RSTRUCT_LENINT(VALUE st)
{
return rb_long2int_inline(internal_RSTRUCT_LEN(st));
}
static inline const VALUE *
RSTRUCT_CONST_PTR(VALUE st)
{
const struct RStruct *p = ((struct RStruct *)(st));
if (RB_FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK)) {
return p->as.ary;
}
else {
return p->as.heap.ptr;
}
}
static inline void
internal_RSTRUCT_SET(VALUE st, long k, VALUE v)
{
rb_obj_write((VALUE)(st), ((VALUE *)(&RSTRUCT_CONST_PTR(st)[k])), (VALUE)(v), "./internal/struct.h", 137);
}
static inline VALUE
internal_RSTRUCT_GET(VALUE st, long k)
{
return RSTRUCT_CONST_PTR(st)[k];
}
static inline const VALUE *
rb_struct_const_heap_ptr(VALUE st)
{
return ((struct RStruct *)(st))->as.heap.ptr;
}
struct gen_ivtbl {
uint32_t numiv;
VALUE ivptr[];
};
int rb_ivar_generic_ivtbl_lookup(VALUE obj, struct gen_ivtbl **);
enum ruby_vminsn_type {
YARVINSN_nop,
YARVINSN_getlocal,
YARVINSN_setlocal,
YARVINSN_getblockparam,
YARVINSN_setblockparam,
YARVINSN_getblockparamproxy,
YARVINSN_getspecial,
YARVINSN_setspecial,
YARVINSN_getinstancevariable,
YARVINSN_setinstancevariable,
YARVINSN_getclassvariable,
YARVINSN_setclassvariable,
YARVINSN_opt_getconstant_path,
YARVINSN_getconstant,
YARVINSN_setconstant,
YARVINSN_getglobal,
YARVINSN_setglobal,
YARVINSN_putnil,
YARVINSN_putself,
YARVINSN_putobject,
YARVINSN_putspecialobject,
YARVINSN_putstring,
YARVINSN_concatstrings,
YARVINSN_anytostring,
YARVINSN_toregexp,
YARVINSN_intern,
YARVINSN_newarray,
YARVINSN_newarraykwsplat,
YARVINSN_duparray,
YARVINSN_duphash,
YARVINSN_expandarray,
YARVINSN_concatarray,
YARVINSN_splatarray,
YARVINSN_newhash,
YARVINSN_newrange,
YARVINSN_pop,
YARVINSN_dup,
YARVINSN_dupn,
YARVINSN_swap,
YARVINSN_opt_reverse,
YARVINSN_topn,
YARVINSN_setn,
YARVINSN_adjuststack,
YARVINSN_defined,
YARVINSN_checkmatch,
YARVINSN_checkkeyword,
YARVINSN_checktype,
YARVINSN_defineclass,
YARVINSN_definemethod,
YARVINSN_definesmethod,
YARVINSN_send,
YARVINSN_opt_send_without_block,
YARVINSN_objtostring,
YARVINSN_opt_str_freeze,
YARVINSN_opt_nil_p,
YARVINSN_opt_str_uminus,
YARVINSN_opt_newarray_max,
YARVINSN_opt_newarray_min,
YARVINSN_invokesuper,
YARVINSN_invokeblock,
YARVINSN_leave,
YARVINSN_throw,
YARVINSN_jump,
YARVINSN_branchif,
YARVINSN_branchunless,
YARVINSN_branchnil,
YARVINSN_once,
YARVINSN_opt_case_dispatch,
YARVINSN_opt_plus,
YARVINSN_opt_minus,
YARVINSN_opt_mult,
YARVINSN_opt_div,
YARVINSN_opt_mod,
YARVINSN_opt_eq,
YARVINSN_opt_neq,
YARVINSN_opt_lt,
YARVINSN_opt_le,
YARVINSN_opt_gt,
YARVINSN_opt_ge,
YARVINSN_opt_ltlt,
YARVINSN_opt_and,
YARVINSN_opt_or,
YARVINSN_opt_aref,
YARVINSN_opt_aset,
YARVINSN_opt_aset_with,
YARVINSN_opt_aref_with,
YARVINSN_opt_length,
YARVINSN_opt_size,
YARVINSN_opt_empty_p,
YARVINSN_opt_succ,
YARVINSN_opt_not,
YARVINSN_opt_regexpmatch2,
YARVINSN_invokebuiltin,
YARVINSN_opt_invokebuiltin_delegate,
YARVINSN_opt_invokebuiltin_delegate_leave,
YARVINSN_getlocal_WC_0,
YARVINSN_getlocal_WC_1,
YARVINSN_setlocal_WC_0,
YARVINSN_setlocal_WC_1,
YARVINSN_putobject_INT2FIX_0_,
YARVINSN_putobject_INT2FIX_1_,
YARVINSN_trace_nop,
YARVINSN_trace_getlocal,
YARVINSN_trace_setlocal,
YARVINSN_trace_getblockparam,
YARVINSN_trace_setblockparam,
YARVINSN_trace_getblockparamproxy,
YARVINSN_trace_getspecial,
YARVINSN_trace_setspecial,
YARVINSN_trace_getinstancevariable,
YARVINSN_trace_setinstancevariable,
YARVINSN_trace_getclassvariable,
YARVINSN_trace_setclassvariable,
YARVINSN_trace_opt_getconstant_path,
YARVINSN_trace_getconstant,
YARVINSN_trace_setconstant,
YARVINSN_trace_getglobal,
YARVINSN_trace_setglobal,
YARVINSN_trace_putnil,
YARVINSN_trace_putself,
YARVINSN_trace_putobject,
YARVINSN_trace_putspecialobject,
YARVINSN_trace_putstring,
YARVINSN_trace_concatstrings,
YARVINSN_trace_anytostring,
YARVINSN_trace_toregexp,
YARVINSN_trace_intern,
YARVINSN_trace_newarray,
YARVINSN_trace_newarraykwsplat,
YARVINSN_trace_duparray,
YARVINSN_trace_duphash,
YARVINSN_trace_expandarray,
YARVINSN_trace_concatarray,
YARVINSN_trace_splatarray,
YARVINSN_trace_newhash,
YARVINSN_trace_newrange,
YARVINSN_trace_pop,
YARVINSN_trace_dup,
YARVINSN_trace_dupn,
YARVINSN_trace_swap,
YARVINSN_trace_opt_reverse,
YARVINSN_trace_topn,
YARVINSN_trace_setn,
YARVINSN_trace_adjuststack,
YARVINSN_trace_defined,
YARVINSN_trace_checkmatch,
YARVINSN_trace_checkkeyword,
YARVINSN_trace_checktype,
YARVINSN_trace_defineclass,
YARVINSN_trace_definemethod,
YARVINSN_trace_definesmethod,
YARVINSN_trace_send,
YARVINSN_trace_opt_send_without_block,
YARVINSN_trace_objtostring,
YARVINSN_trace_opt_str_freeze,
YARVINSN_trace_opt_nil_p,
YARVINSN_trace_opt_str_uminus,
YARVINSN_trace_opt_newarray_max,
YARVINSN_trace_opt_newarray_min,
YARVINSN_trace_invokesuper,
YARVINSN_trace_invokeblock,
YARVINSN_trace_leave,
YARVINSN_trace_throw,
YARVINSN_trace_jump,
YARVINSN_trace_branchif,
YARVINSN_trace_branchunless,
YARVINSN_trace_branchnil,
YARVINSN_trace_once,
YARVINSN_trace_opt_case_dispatch,
YARVINSN_trace_opt_plus,
YARVINSN_trace_opt_minus,
YARVINSN_trace_opt_mult,
YARVINSN_trace_opt_div,
YARVINSN_trace_opt_mod,
YARVINSN_trace_opt_eq,
YARVINSN_trace_opt_neq,
YARVINSN_trace_opt_lt,
YARVINSN_trace_opt_le,
YARVINSN_trace_opt_gt,
YARVINSN_trace_opt_ge,
YARVINSN_trace_opt_ltlt,
YARVINSN_trace_opt_and,
YARVINSN_trace_opt_or,
YARVINSN_trace_opt_aref,
YARVINSN_trace_opt_aset,
YARVINSN_trace_opt_aset_with,
YARVINSN_trace_opt_aref_with,
YARVINSN_trace_opt_length,
YARVINSN_trace_opt_size,
YARVINSN_trace_opt_empty_p,
YARVINSN_trace_opt_succ,
YARVINSN_trace_opt_not,
YARVINSN_trace_opt_regexpmatch2,
YARVINSN_trace_invokebuiltin,
YARVINSN_trace_opt_invokebuiltin_delegate,
YARVINSN_trace_opt_invokebuiltin_delegate_leave,
YARVINSN_trace_getlocal_WC_0,
YARVINSN_trace_getlocal_WC_1,
YARVINSN_trace_setlocal_WC_0,
YARVINSN_trace_setlocal_WC_1,
YARVINSN_trace_putobject_INT2FIX_0_,
YARVINSN_trace_putobject_INT2FIX_1_,
VM_INSTRUCTION_SIZE
};
extern rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid);
extern void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
int argc, const VALUE *argv, int priv);
static rb_control_frame_t *vm_get_ruby_level_caller_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp);
static VALUE
ruby_vm_special_exception_copy(VALUE exc)
{
VALUE e = rb_obj_alloc(rb_class_real(RBASIC_CLASS(exc)));
rb_obj_copy_ivar(e, exc);
return e;
}
__attribute__((__noreturn__)) static void ec_stack_overflow(rb_execution_context_t *ec, int);
static void
ec_stack_overflow(rb_execution_context_t *ec, int setup)
{
VALUE mesg = rb_ec_vm_ptr(ec)->special_exceptions[ruby_error_sysstack];
ec->raised_flag = RAISED_STACKOVERFLOW;
if (setup) {
VALUE at = rb_ec_backtrace_object(ec);
mesg = ruby_vm_special_exception_copy(mesg);
rb_ivar_set(mesg, idBt, at);
rb_ivar_set(mesg, idBt_locations, at);
}
ec->errinfo = mesg;
rb_ec_tag_jump(ec, RUBY_TAG_RAISE);
}
__attribute__((__noreturn__)) static void vm_stackoverflow(void);
__attribute__((__noinline__)) static __attribute__((__cold__)) void vm_stackoverflow(void);
static void
vm_stackoverflow(void)
{
ec_stack_overflow(rb_current_execution_context(1), 1);
}
__attribute__((__noreturn__)) static void rb_ec_stack_overflow(rb_execution_context_t *ec, int crit);
static void
rb_ec_stack_overflow(rb_execution_context_t *ec, int crit)
{
if (rb_during_gc()) {
rb_bug("system stack overflow during GC. Faulty native extension?");
}
if (crit) {
ec->raised_flag = RAISED_STACKOVERFLOW;
ec->errinfo = rb_ec_vm_ptr(ec)->special_exceptions[ruby_error_stackfatal];
rb_ec_tag_jump(ec, RUBY_TAG_RAISE);
}
ec_stack_overflow(ec, 1);
}
__extension__ _Static_assert((-2) == -2, "VM_ENV_DATA_INDEX_ME_CREF" ": " "VM_ENV_DATA_INDEX_ME_CREF == -2");
__extension__ _Static_assert((-1) == -1, "VM_ENV_DATA_INDEX_SPECVAL" ": " "VM_ENV_DATA_INDEX_SPECVAL == -1");
__extension__ _Static_assert(( 0) == -0, "VM_ENV_DATA_INDEX_FLAGS" ": " "VM_ENV_DATA_INDEX_FLAGS == -0");
static void
vm_push_frame(rb_execution_context_t *ec,
const rb_iseq_t *iseq,
VALUE type,
VALUE self,
VALUE specval,
VALUE cref_or_me,
const VALUE *pc,
VALUE *sp,
int local_size,
int stack_max)
{
rb_control_frame_t *const cfp = ((ec->cfp)-1);
;
((void)0);
do { __extension__ _Static_assert(sizeof(*(sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*(sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*(cfp)) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*(cfp)) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&(sp)[(local_size + stack_max)]; if ((__builtin_expect(!!((cfp) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
;
for (int i=0; i < local_size; i++) {
*sp++ = ((VALUE)RUBY_Qnil);
}
*sp++ = cref_or_me;
*sp++ = specval ;
*sp++ = type;
*cfp = (const struct rb_control_frame_struct) {
.pc = pc,
.sp = sp,
.iseq = iseq,
.self = self,
.ep = sp - 1,
.block_code = ((void *)0),
.__bp__ = sp,
.jit_return = ((void *)0)
};
__atomic_signal_fence (memory_order_seq_cst);
ec->cfp = cfp;
if (0 == 2) {
rb_vmdebug_stack_dump_raw(rb_current_execution_context(1), rb_current_execution_context(1)->cfp);
}
;
}static inline
void
rb_vm_pop_frame_no_int(rb_execution_context_t *ec)
{
rb_control_frame_t *cfp = ec->cfp;
if ((((0) > 0) ? (0) : 0) >= 4) rb_gc_verify_internal_consistency();
if (0 == 2) rb_vmdebug_stack_dump_raw(rb_current_execution_context(1), rb_current_execution_context(1)->cfp);
ec->cfp = ((cfp)+1);
}
static inline int
vm_pop_frame(rb_execution_context_t *ec, rb_control_frame_t *cfp, const VALUE *ep)
{
VALUE flags = ep[( 0)];
if ((((0) > 0) ? (0) : 0) >= 4) rb_gc_verify_internal_consistency();
if (0 == 2) rb_vmdebug_stack_dump_raw(rb_current_execution_context(1), rb_current_execution_context(1)->cfp);
rb_vm_check_ints(ec);
ec->cfp = ((cfp)+1);
return flags & VM_FRAME_FLAG_FINISH;
}
static void
rb_vm_pop_frame(rb_execution_context_t *ec)
{
vm_pop_frame(ec, ec->cfp, ec->cfp->ep);
}static inline
VALUE
rb_vm_push_frame_fname(rb_execution_context_t *ec, VALUE fname)
{
rb_iseq_t *rb_iseq_alloc_with_dummy_path(VALUE fname);
rb_iseq_t *dmy_iseq = rb_iseq_alloc_with_dummy_path(fname);
vm_push_frame(ec,
dmy_iseq,
VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH,
ec->cfp->self,
0,
((VALUE)RUBY_Qfalse),
((void *)0),
ec->cfp->sp,
0,
0);
return (VALUE)dmy_iseq;
}
static inline VALUE
rb_arity_error_new(int argc, int min, int max)
{
VALUE err_mess = rb_sprintf("wrong number of arguments (given %d, expected %d", argc, min);
if (min == max) {
}
else if (max == (-1)) {
((__builtin_constant_p("+") ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((err_mess), ("+")));
}
else {
rb_str_catf(err_mess, "..%d", max);
}
((__builtin_constant_p(")") ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((err_mess), (")")));
return rb_exc_new_str(rb_eArgError, err_mess);
}
static void
rb_error_arity(int argc, int min, int max)
{
rb_exc_raise(rb_arity_error_new(argc, min, max));
}
__attribute__((__noinline__)) static void vm_env_write_slowpath(const VALUE *ep, int index, VALUE v);
static void
vm_env_write_slowpath(const VALUE *ep, int index, VALUE v)
{
rb_gc_writebarrier_remember(VM_ENV_ENVVAL(ep));
VM_FORCE_WRITE(&ep[index], v);
VM_ENV_FLAGS_UNSET(ep, VM_ENV_FLAG_WB_REQUIRED);
((void)0);
}
static inline void
vm_env_write(const VALUE *ep, int index, VALUE v)
{
VALUE flags = ep[( 0)];
if ((__builtin_expect(!!((flags & VM_ENV_FLAG_WB_REQUIRED) == 0), 1))) {
VM_STACK_ENV_WRITE(ep, index, v);
}
else {
vm_env_write_slowpath(ep, index, v);
}
}
static VALUE
rb_vm_bh_to_procval(const rb_execution_context_t *ec, VALUE block_handler)
{
if (block_handler == 0) {
return ((VALUE)RUBY_Qnil);
}
else {
switch (vm_block_handler_type(block_handler)) {
case block_handler_type_iseq:
case block_handler_type_ifunc:
return rb_vm_make_proc(ec, VM_BH_TO_CAPT_BLOCK(block_handler), rb_cProc);
case block_handler_type_symbol:
return rb_sym_to_proc(VM_BH_TO_SYMBOL(block_handler));
case block_handler_type_proc:
return VM_BH_TO_PROC(block_handler);
default:
__builtin_unreachable();
}
}
}
static inline struct vm_svar *
lep_svar(const rb_execution_context_t *ec, const VALUE *lep)
{
VALUE svar;
if (lep && (ec == ((void *)0) || ec->root_lep != lep)) {
svar = lep[(-2)];
}
else {
svar = ec->root_svar;
}
((void)0);
return (struct vm_svar *)svar;
}
static inline void
lep_svar_write(const rb_execution_context_t *ec, const VALUE *lep, const struct vm_svar *svar)
{
((void)0);
if (lep && (ec == ((void *)0) || ec->root_lep != lep)) {
vm_env_write(lep, (-2), (VALUE)svar);
}
else {
rb_obj_write((VALUE)(rb_ec_thread_ptr(ec)->self), ((VALUE *)(&ec->root_svar)), (VALUE)(svar), "./vm_insnhelper.c", 591);
}
}
static VALUE
lep_svar_get(const rb_execution_context_t *ec, const VALUE *lep, rb_num_t key)
{
const struct vm_svar *svar = lep_svar(ec, lep);
if ((VALUE)svar == ((VALUE)RUBY_Qfalse) || imemo_type((VALUE)svar) != imemo_svar) return ((VALUE)RUBY_Qnil);
switch (key) {
case VM_SVAR_LASTLINE:
return svar->lastline;
case VM_SVAR_BACKREF:
return svar->backref;
default: {
const VALUE ary = svar->others;
if (RB_NIL_P(ary)) {
return ((VALUE)RUBY_Qnil);
}
else {
return rb_ary_entry(ary, key - VM_SVAR_EXTRA_START);
}
}
}
}
static struct vm_svar *
svar_new(VALUE obj)
{
return (struct vm_svar *)rb_imemo_new(imemo_svar, ((VALUE)RUBY_Qnil), ((VALUE)RUBY_Qnil), ((VALUE)RUBY_Qnil), obj);
}
static void
lep_svar_set(const rb_execution_context_t *ec, const VALUE *lep, rb_num_t key, VALUE val)
{
struct vm_svar *svar = lep_svar(ec, lep);
if ((VALUE)svar == ((VALUE)RUBY_Qfalse) || imemo_type((VALUE)svar) != imemo_svar) {
lep_svar_write(ec, lep, svar = svar_new((VALUE)svar));
}
switch (key) {
case VM_SVAR_LASTLINE:
rb_obj_write((VALUE)(svar), ((VALUE *)(&svar->lastline)), (VALUE)(val), "./vm_insnhelper.c", 637);
return;
case VM_SVAR_BACKREF:
rb_obj_write((VALUE)(svar), ((VALUE *)(&svar->backref)), (VALUE)(val), "./vm_insnhelper.c", 640);
return;
default: {
VALUE ary = svar->others;
if (RB_NIL_P(ary)) {
rb_obj_write((VALUE)(svar), ((VALUE *)(&svar->others)), (VALUE)(ary = rb_ary_new()), "./vm_insnhelper.c", 646);
}
rb_ary_store(ary, key - VM_SVAR_EXTRA_START, val);
}
}
}
static inline VALUE
vm_getspecial(const rb_execution_context_t *ec, const VALUE *lep, rb_num_t key, rb_num_t type)
{
VALUE val;
if (type == 0) {
val = lep_svar_get(ec, lep, key);
}
else {
VALUE backref = lep_svar_get(ec, lep, VM_SVAR_BACKREF);
if (type & 0x01) {
switch (type >> 1) {
case '&':
val = rb_reg_last_match(backref);
break;
case '`':
val = rb_reg_match_pre(backref);
break;
case '\'':
val = rb_reg_match_post(backref);
break;
case '+':
val = rb_reg_match_last(backref);
break;
default:
rb_bug("unexpected back-ref");
}
}
else {
val = rb_reg_nth_match((int)(type >> 1), backref);
}
}
return val;
}
__attribute__((__pure__)) static rb_callable_method_entry_t *check_method_entry(VALUE obj, int can_be_svar);
static rb_callable_method_entry_t *
check_method_entry(VALUE obj, int can_be_svar)
{
if (obj == ((VALUE)RUBY_Qfalse)) return ((void *)0);
switch (imemo_type(obj)) {
case imemo_ment:
return (rb_callable_method_entry_t *)obj;
case imemo_cref:
return ((void *)0);
case imemo_svar:
if (can_be_svar) {
return check_method_entry(((struct vm_svar *)obj)->cref_or_me, 0);
}
default:
return ((void *)0);
}
}
static const rb_callable_method_entry_t *
rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
{
const VALUE *ep = cfp->ep;
rb_callable_method_entry_t *me;
while (!VM_ENV_LOCAL_P(ep)) {
if ((me = check_method_entry(ep[(-2)], 0)) != ((void *)0)) return me;
ep = VM_ENV_PREV_EP(ep);
}
return check_method_entry(ep[(-2)], 1);
}
static const rb_iseq_t *
method_entry_iseqptr(const rb_callable_method_entry_t *me)
{
switch (me->def->type) {
case VM_METHOD_TYPE_ISEQ:
return me->def->body.iseq.iseqptr;
default:
return ((void *)0);
}
}
static rb_cref_t *
method_entry_cref(const rb_callable_method_entry_t *me)
{
switch (me->def->type) {
case VM_METHOD_TYPE_ISEQ:
return me->def->body.iseq.cref;
default:
return ((void *)0);
}
}
__attribute__((__pure__)) static rb_cref_t *check_cref(VALUE, int);
static rb_cref_t *
check_cref(VALUE obj, int can_be_svar)
{
if (obj == ((VALUE)RUBY_Qfalse)) return ((void *)0);
switch (imemo_type(obj)) {
case imemo_ment:
return method_entry_cref((rb_callable_method_entry_t *)obj);
case imemo_cref:
return (rb_cref_t *)obj;
case imemo_svar:
if (can_be_svar) {
return check_cref(((struct vm_svar *)obj)->cref_or_me, 0);
}
default:
return ((void *)0);
}
}
static inline rb_cref_t *
vm_env_cref(const VALUE *ep)
{
rb_cref_t *cref;
while (!VM_ENV_LOCAL_P(ep)) {
if ((cref = check_cref(ep[(-2)], 0)) != ((void *)0)) return cref;
ep = VM_ENV_PREV_EP(ep);
}
return check_cref(ep[(-2)], 1);
}
static int
is_cref(const VALUE v, int can_be_svar)
{
if (RB_TYPE_P(v, RUBY_T_IMEMO)) {
switch (imemo_type(v)) {
case imemo_cref:
return 1;
case imemo_svar:
if (can_be_svar) return is_cref(((struct vm_svar *)v)->cref_or_me, 0);
default:
break;
}
}
return 0;
}
static int
vm_env_cref_by_cref(const VALUE *ep)
{
while (!VM_ENV_LOCAL_P(ep)) {
if (is_cref(ep[(-2)], 0)) return 1;
ep = VM_ENV_PREV_EP(ep);
}
return is_cref(ep[(-2)], 1);
}
static rb_cref_t *
cref_replace_with_duplicated_cref_each_frame(const VALUE *vptr, int can_be_svar, VALUE parent)
{
const VALUE v = *vptr;
rb_cref_t *cref, *new_cref;
if (RB_TYPE_P(v, RUBY_T_IMEMO)) {
switch (imemo_type(v)) {
case imemo_cref:
cref = (rb_cref_t *)v;
new_cref = vm_cref_dup(cref);
if (parent) {
rb_obj_write((VALUE)(parent), ((VALUE *)(vptr)), (VALUE)(new_cref), "./vm_insnhelper.c", 832);
}
else {
VM_FORCE_WRITE(vptr, (VALUE)new_cref);
}
return (rb_cref_t *)new_cref;
case imemo_svar:
if (can_be_svar) {
return cref_replace_with_duplicated_cref_each_frame(&((struct vm_svar *)v)->cref_or_me, 0, v);
}
case imemo_ment:
rb_bug("cref_replace_with_duplicated_cref_each_frame: unreachable");
default:
break;
}
}
return ((void *)0);
}
static rb_cref_t *
vm_cref_replace_with_duplicated_cref(const VALUE *ep)
{
if (vm_env_cref_by_cref(ep)) {
rb_cref_t *cref;
VALUE envval;
while (!VM_ENV_LOCAL_P(ep)) {
envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) : ((VALUE)RUBY_Qfalse);
if ((cref = cref_replace_with_duplicated_cref_each_frame(&ep[(-2)], 0, envval)) != ((void *)0)) {
return cref;
}
ep = VM_ENV_PREV_EP(ep);
}
envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) : ((VALUE)RUBY_Qfalse);
return cref_replace_with_duplicated_cref_each_frame(&ep[(-2)], 1, envval);
}
else {
rb_bug("vm_cref_dup: unreachable");
}
}
static rb_cref_t *
vm_get_cref(const VALUE *ep)
{
rb_cref_t *cref = vm_env_cref(ep);
if (cref != ((void *)0)) {
return cref;
}
else {
rb_bug("vm_get_cref: unreachable");
}
}static inline
rb_cref_t *
rb_vm_get_cref(const VALUE *ep)
{
return vm_get_cref(ep);
}
static rb_cref_t *
vm_ec_cref(const rb_execution_context_t *ec)
{
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
if (cfp == ((void *)0)) {
return ((void *)0);
}
return vm_get_cref(cfp->ep);
}
static const rb_cref_t *
vm_get_const_key_cref(const VALUE *ep)
{
const rb_cref_t *cref = vm_get_cref(ep);
const rb_cref_t *key_cref = cref;
while (cref) {
if (RB_FL_TEST(CREF_CLASS(cref), ((VALUE)RUBY_FL_SINGLETON)) ||
RB_FL_TEST(CREF_CLASS(cref), ((VALUE)RUBY_FL_USER1))) {
return key_cref;
}
cref = CREF_NEXT(cref);
}
return ((void *)0);
}static inline
void
rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
{
rb_cref_t *new_cref;
while (cref) {
if (CREF_CLASS(cref) == old_klass) {
new_cref = vm_cref_new_use_prev(new_klass, METHOD_VISI_UNDEF, 0, cref, 0);
*new_cref_ptr = new_cref;
return;
}
new_cref = vm_cref_new_use_prev(CREF_CLASS(cref), METHOD_VISI_UNDEF, 0, cref, 0);
cref = CREF_NEXT(cref);
*new_cref_ptr = new_cref;
new_cref_ptr = &new_cref->next;
}
*new_cref_ptr = ((void *)0);
}
static rb_cref_t *
vm_cref_push(const rb_execution_context_t *ec, VALUE klass, const VALUE *ep, int pushed_by_eval, int singleton)
{
rb_cref_t *prev_cref = ((void *)0);
if (ep) {
prev_cref = vm_env_cref(ep);
}
else {
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(ec, ec->cfp);
if (cfp) {
prev_cref = vm_env_cref(cfp->ep);
}
}
return vm_cref_new(klass, METHOD_VISI_PUBLIC, 0, prev_cref, pushed_by_eval, singleton);
}
static inline VALUE
vm_get_cbase(const VALUE *ep)
{
const rb_cref_t *cref = vm_get_cref(ep);
return CREF_CLASS_FOR_DEFINITION(cref);
}
static inline VALUE
vm_get_const_base(const VALUE *ep)
{
const rb_cref_t *cref = vm_get_cref(ep);
while (cref) {
if (!CREF_PUSHED_BY_EVAL(cref)) {
return CREF_CLASS_FOR_DEFINITION(cref);
}
cref = CREF_NEXT(cref);
}
return ((VALUE)RUBY_Qundef);
}
static inline void
vm_check_if_namespace(VALUE klass)
{
if (!RB_TYPE_P(klass, RUBY_T_CLASS) && !RB_TYPE_P(klass, RUBY_T_MODULE)) {
rb_raise(rb_eTypeError, "%+""l""i" "\v"" is not a class/module", klass);
}
}
static inline void
vm_ensure_not_refinement_module(VALUE self)
{
if (RB_TYPE_P(self, RUBY_T_MODULE) && RB_FL_TEST(self, RMODULE_IS_REFINEMENT)) {
rb_warn("not defined at the refinement, but at the outer class/module");
}
}
static inline VALUE
vm_get_iclass(const rb_control_frame_t *cfp, VALUE klass)
{
return klass;
}
static inline VALUE
vm_get_ev_const(rb_execution_context_t *ec, VALUE orig_klass, ID id, _Bool allow_nil, int is_defined)
{
void rb_const_warn_if_deprecated(const rb_const_entry_t *ce, VALUE klass, ID id);
VALUE val;
if (RB_NIL_P(orig_klass) && allow_nil) {
const rb_cref_t *root_cref = vm_get_cref(ec->cfp->ep);
const rb_cref_t *cref;
VALUE klass = ((VALUE)RUBY_Qnil);
while (root_cref && CREF_PUSHED_BY_EVAL(root_cref)) {
root_cref = CREF_NEXT(root_cref);
}
cref = root_cref;
while (cref && CREF_NEXT(cref)) {
if (CREF_PUSHED_BY_EVAL(cref)) {
klass = ((VALUE)RUBY_Qnil);
}
else {
klass = CREF_CLASS(cref);
}
cref = CREF_NEXT(cref);
if (!RB_NIL_P(klass)) {
VALUE av, am = 0;
rb_const_entry_t *ce;
search_continue:
if ((ce = rb_const_lookup(klass, id))) {
rb_const_warn_if_deprecated(ce, klass, id);
val = ce->value;
if (RB_UNDEF_P(val)) {
if (am == klass) break;
am = klass;
if (is_defined) return 1;
if (rb_autoloading_value(klass, id, &av, ((void *)0))) return av;
rb_autoload_load(klass, id);
goto search_continue;
}
else {
if (is_defined) {
return 1;
}
else {
if ((__builtin_expect(!!(!rb_ractor_main_p()), 0))) {
if (!rb_ractor_shareable_p(val)) {
rb_raise(rb_eRactorIsolationError,
"can not access non-shareable objects in constant %""l""i" "\v""::%s by non-main ractor.", rb_class_path(klass), rb_id2name(id));
}
}
return val;
}
}
}
}
}
if (root_cref && !RB_NIL_P(CREF_CLASS(root_cref))) {
klass = vm_get_iclass(ec->cfp, CREF_CLASS(root_cref));
}
else {
klass = rb_class_of(ec->cfp->self);
}
if (is_defined) {
return rb_const_defined(klass, id);
}
else {
return rb_const_get(klass, id);
}
}
else {
vm_check_if_namespace(orig_klass);
if (is_defined) {
return rb_public_const_defined_from(orig_klass, id);
}
else {
return rb_public_const_get_from(orig_klass, id);
}
}
}static inline
VALUE
rb_vm_get_ev_const(rb_execution_context_t *ec, VALUE orig_klass, ID id, VALUE allow_nil)
{
return vm_get_ev_const(ec, orig_klass, id, allow_nil == ((VALUE)RUBY_Qtrue), 0);
}
static inline VALUE
vm_get_ev_const_chain(rb_execution_context_t *ec, const ID *segments)
{
VALUE val = ((VALUE)RUBY_Qnil);
int idx = 0;
int allow_nil = 1;
if (segments[0] == idNULL) {
val = rb_cObject;
idx++;
allow_nil = 0;
}
while (segments[idx]) {
ID id = segments[idx++];
val = vm_get_ev_const(ec, val, id, allow_nil, 0);
allow_nil = 0;
}
return val;
}
static inline VALUE
vm_get_cvar_base(const rb_cref_t *cref, const rb_control_frame_t *cfp, int top_level_raise)
{
VALUE klass;
if (!cref) {
rb_bug("vm_get_cvar_base: no cref");
}
while (CREF_NEXT(cref) &&
(RB_NIL_P(CREF_CLASS(cref)) || RB_FL_TEST(CREF_CLASS(cref), ((VALUE)RUBY_FL_SINGLETON)) ||
CREF_PUSHED_BY_EVAL(cref) || CREF_SINGLETON(cref))) {
cref = CREF_NEXT(cref);
}
if (top_level_raise && !CREF_NEXT(cref)) {
rb_raise(rb_eRuntimeError, "class variable access from toplevel");
}
klass = vm_get_iclass(cfp, CREF_CLASS(cref));
if (RB_NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class variables available");
}
return klass;
}
__attribute__ ((__always_inline__)) static void fill_ivar_cache(const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr, attr_index_t index, shape_id_t shape_id);
static inline void
fill_ivar_cache(const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr, attr_index_t index, shape_id_t shape_id)
{
if (is_attr) {
vm_cc_attr_index_set(cc, index, shape_id);
}
else {
vm_ic_attr_index_set(iseq, ic, index, shape_id);
}
}
__attribute__ ((__always_inline__)) static VALUE vm_getivar(VALUE, ID, const rb_iseq_t *, IVC, const struct rb_callcache *, int);
static inline VALUE
vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr)
{
VALUE val = ((VALUE)RUBY_Qundef);
shape_id_t shape_id;
VALUE * ivar_list;
if (RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qnil);
}
shape_id = RBASIC_SHAPE_ID(obj);
switch (RB_BUILTIN_TYPE(obj)) {
case RUBY_T_OBJECT:
ivar_list = ROBJECT_IVPTR(obj);
((void)0);
break;
case RUBY_T_CLASS:
case RUBY_T_MODULE:
{
if ((__builtin_expect(!!(!rb_ractor_main_p()), 0))) {
goto general_path;
}
ivar_list = (((rb_classext_t *)((char *)(obj) + sizeof(struct RClass)))->iv_ptr);
break;
}
default:
if (RB_FL_TEST_RAW(obj, ((VALUE)RUBY_FL_EXIVAR))) {
struct gen_ivtbl *ivtbl;
rb_gen_ivtbl_get(obj, id, &ivtbl);
ivar_list = ivtbl->ivptr;
}
else {
return ((VALUE)RUBY_Qnil);
}
}
shape_id_t cached_id;
attr_index_t index;
if (is_attr) {
vm_cc_atomic_shape_and_index(cc, &cached_id, &index);
}
else {
vm_ic_atomic_shape_and_index(ic, &cached_id, &index);
}
if ((__builtin_expect(!!(cached_id == shape_id), 1))) {
((void)0);
if (index == (attr_index_t)-1) {
return ((VALUE)RUBY_Qnil);
}
val = ivar_list[index];
((void)0);
}
else {
rb_shape_t *shape = rb_shape_get_shape_by_id(shape_id);
if (shape_id == ((5 * 2) + 1)) {
if (!rb_st_lookup(ROBJECT_IV_HASH(obj), id, &val)) {
val = ((VALUE)RUBY_Qnil);
}
}
else {
if (rb_shape_get_iv_index(shape, id, &index)) {
fill_ivar_cache(iseq, ic, cc, is_attr, index, shape_id);
val = ivar_list[index];
((void)0);
}
else {
if (is_attr) {
vm_cc_attr_index_initialize(cc, shape_id);
}
else {
vm_ic_attr_index_initialize(ic, shape_id);
}
val = ((VALUE)RUBY_Qnil);
}
}
}
((void)0);
return val;
general_path:
((void)0);
if (is_attr) {
return rb_attr_get(obj, id);
}
else {
return rb_ivar_get(obj, id);
}
}
static void
populate_cache(attr_index_t index, shape_id_t next_shape_id, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, _Bool is_attr)
{
((void)0);
if (is_attr) {
vm_cc_attr_index_set(cc, index, next_shape_id);
}
else {
vm_ic_attr_index_set(iseq, ic, index, next_shape_id);
}
}
__attribute__ ((__always_inline__)) static VALUE vm_setivar_slowpath(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr);
__attribute__((__noinline__)) static VALUE vm_setivar_slowpath_ivar(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic);
__attribute__((__noinline__)) static VALUE vm_setivar_slowpath_attr(VALUE obj, ID id, VALUE val, const struct rb_callcache *cc);
static VALUE
vm_setivar_slowpath(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr)
{
switch (RB_BUILTIN_TYPE(obj)) {
case RUBY_T_OBJECT:
{
do { VALUE frozen_obj = (obj); if ((__builtin_expect(!!(RB_OBJ_FROZEN(frozen_obj)), 0))) { rb_error_frozen_object(frozen_obj); } } while (0);
attr_index_t index = rb_obj_ivar_set(obj, id, val);
shape_id_t next_shape_id = ROBJECT_SHAPE_ID(obj);
if (next_shape_id != ((5 * 2) + 1)) {
populate_cache(index, next_shape_id, id, iseq, ic, cc, is_attr);
}
((void)0);
return val;
}
case RUBY_T_CLASS:
case RUBY_T_MODULE:
break;
default:
{
rb_ivar_set(obj, id, val);
shape_id_t next_shape_id = rb_shape_get_shape_id(obj);
rb_shape_t *next_shape = rb_shape_get_shape_by_id(next_shape_id);
attr_index_t index;
if (rb_shape_get_iv_index(next_shape, id, &index)) {
if (index >= (attr_index_t)(-1)) {
rb_raise(rb_eArgError, "too many instance variables");
}
populate_cache(index, next_shape_id, id, iseq, ic, cc, is_attr);
}
else {
rb_bug("didn't find the id\n");
}
return val;
}
}
((void)0);
return rb_ivar_set(obj, id, val);
}
static VALUE
vm_setivar_slowpath_ivar(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic)
{
return vm_setivar_slowpath(obj, id, val, iseq, ic, ((void *)0), 0);
}
static VALUE
vm_setivar_slowpath_attr(VALUE obj, ID id, VALUE val, const struct rb_callcache *cc)
{
return vm_setivar_slowpath(obj, id, val, ((void *)0), ((void *)0), cc, 1);
}
__attribute__((__noinline__)) static VALUE vm_setivar_default(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t index);
static VALUE
vm_setivar_default(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t index)
{
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
struct gen_ivtbl *ivtbl = 0;
if (shape_id == dest_shape_id) {
((void)0);
rb_gen_ivtbl_get(obj, 0, &ivtbl);
}
else if (dest_shape_id != (((uintptr_t)1 << 32) - 1)) {
rb_shape_t * dest_shape = rb_shape_get_shape_by_id(dest_shape_id);
shape_id_t source_shape_id = dest_shape->parent_id;
if (shape_id == source_shape_id && dest_shape->edge_name == id && dest_shape->type == SHAPE_IVAR) {
ivtbl = rb_ensure_generic_iv_list_size(obj, dest_shape, index + 1);
RBASIC_SET_SHAPE_ID(obj, dest_shape_id);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
else {
return ((VALUE)RUBY_Qundef);
}
VALUE *ptr = ivtbl->ivptr;
rb_obj_write((VALUE)(obj), ((VALUE *)(&ptr[index])), (VALUE)(val), "./vm_insnhelper.c", 1428);
((void)0);
return val;
}
static inline VALUE
vm_setivar(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t index)
{
switch (RB_BUILTIN_TYPE(obj)) {
case RUBY_T_OBJECT:
{
((void)0);
shape_id_t shape_id = ROBJECT_SHAPE_ID(obj);
((void)0);
if ((__builtin_expect(!!(shape_id == dest_shape_id), 1))) {
((void)0);
((void)0);
}
else if (dest_shape_id != (((uintptr_t)1 << 32) - 1)) {
rb_shape_t *dest_shape = rb_shape_get_shape_by_id(dest_shape_id);
shape_id_t source_shape_id = dest_shape->parent_id;
if (shape_id == source_shape_id && dest_shape->edge_name == id) {
((void)0);
ROBJECT_SET_SHAPE_ID(obj, dest_shape_id);
((void)0);
((void)0);
}
else {
break;
}
}
else {
break;
}
VALUE *ptr = ROBJECT_IVPTR(obj);
((void)0);
rb_obj_write((VALUE)(obj), ((VALUE *)(&ptr[index])), (VALUE)(val), "./vm_insnhelper.c", 1474);
((void)0);
return val;
}
break;
case RUBY_T_CLASS:
case RUBY_T_MODULE:
((void)0);
default:
break;
}
return ((VALUE)RUBY_Qundef);
}
static VALUE
update_classvariable_cache(const rb_iseq_t *iseq, VALUE klass, ID id, const rb_cref_t * cref, ICVARC ic)
{
VALUE defined_class = 0;
VALUE cvar_value = rb_cvar_find(klass, id, &defined_class);
if (RB_TYPE_P(defined_class, RUBY_T_ICLASS)) {
defined_class = ((struct RBasic *)(defined_class))->klass;
}
struct rb_id_table *rb_cvc_tbl = (((rb_classext_t *)((char *)(defined_class) + sizeof(struct RClass)))->cvc_tbl);
if (!rb_cvc_tbl) {
rb_bug("the cvc table should be set");
}
VALUE ent_data;
if (!rb_id_table_lookup(rb_cvc_tbl, id, &ent_data)) {
rb_bug("should have cvar cache entry");
}
struct rb_cvar_class_tbl_entry *ent = (void *)ent_data;
ent->global_cvar_state = (ruby_vm_global_cvar_state);
ent->cref = cref;
ic->entry = ent;
((void)0);
(rb_obj_written((VALUE)(iseq), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(ent->cref), "./vm_insnhelper.c", 1518));
(rb_obj_written((VALUE)(iseq), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(ent->class_value), "./vm_insnhelper.c", 1519));
(rb_obj_written((VALUE)(ent->class_value), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(ent->cref), "./vm_insnhelper.c", 1520));
return cvar_value;
}
static inline VALUE
vm_getclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *reg_cfp, ID id, ICVARC ic)
{
const rb_cref_t *cref;
cref = vm_get_cref(((((reg_cfp)->ep))));
if (ic->entry && ic->entry->global_cvar_state == (ruby_vm_global_cvar_state) && ic->entry->cref == cref && (__builtin_expect(!!(rb_ractor_main_p()), 1))) {
((void)0);
VALUE v = rb_ivar_lookup(ic->entry->class_value, id, ((VALUE)RUBY_Qundef));
((void)0);
return v;
}
VALUE klass = vm_get_cvar_base(cref, reg_cfp, 1);
return update_classvariable_cache(iseq, klass, id, cref, ic);
}static inline
VALUE
rb_vm_getclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, ICVARC ic)
{
return vm_getclassvariable(iseq, cfp, id, ic);
}
static inline void
vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *reg_cfp, ID id, VALUE val, ICVARC ic)
{
const rb_cref_t *cref;
cref = vm_get_cref(((((reg_cfp)->ep))));
if (ic->entry && ic->entry->global_cvar_state == (ruby_vm_global_cvar_state) && ic->entry->cref == cref && (__builtin_expect(!!(rb_ractor_main_p()), 1))) {
((void)0);
rb_class_ivar_set(ic->entry->class_value, id, val);
return;
}
VALUE klass = vm_get_cvar_base(cref, reg_cfp, 1);
rb_cvar_set(klass, id, val);
update_classvariable_cache(iseq, klass, id, cref, ic);
}static inline
void
rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic)
{
vm_setclassvariable(iseq, cfp, id, val, ic);
}
static inline VALUE
vm_getinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, IVC ic)
{
return vm_getivar(obj, id, iseq, ic, ((void *)0), 0);
}
static inline void
vm_setinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, VALUE val, IVC ic)
{
if (RB_SPECIAL_CONST_P(obj)) {
rb_error_frozen_object(obj);
return;
}
shape_id_t dest_shape_id;
attr_index_t index;
vm_ic_atomic_shape_and_index(ic, &dest_shape_id, &index);
if ((__builtin_expect(!!(RB_UNDEF_P(vm_setivar(obj, id, val, dest_shape_id, index))), 0))) {
switch (RB_BUILTIN_TYPE(obj)) {
case RUBY_T_OBJECT:
case RUBY_T_CLASS:
case RUBY_T_MODULE:
break;
default:
if (!RB_UNDEF_P(vm_setivar_default(obj, id, val, dest_shape_id, index))) {
return;
}
}
vm_setivar_slowpath_ivar(obj, id, val, iseq, ic);
}
}static inline
void
rb_vm_setinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, VALUE val, IVC ic)
{
vm_setinstancevariable(iseq, obj, id, val, ic);
}
static VALUE
vm_throw_continue(const rb_execution_context_t *ec, VALUE err)
{
if (RB_FIXNUM_P(err)) {
ec->tag->state = RB_FIX2INT(err);
}
else if (RB_SYMBOL_P(err)) {
ec->tag->state = RUBY_TAG_THROW;
}
else if (imemo_throw_data_p((VALUE)err)) {
ec->tag->state = THROW_DATA_STATE((struct vm_throw_data *)err);
}
else {
ec->tag->state = RUBY_TAG_RAISE;
}
return err;
}
static VALUE
vm_throw_start(const rb_execution_context_t *ec, rb_control_frame_t *const reg_cfp, enum ruby_tag_type state,
const int flag, const VALUE throwobj)
{
const rb_control_frame_t *escape_cfp = ((void *)0);
const rb_control_frame_t * const eocfp = RUBY_VM_END_CONTROL_FRAME(ec);
if (flag != 0) {
}
else if (state == RUBY_TAG_BREAK) {
int is_orphan = 1;
const VALUE *ep = ((((reg_cfp)->ep)));
const rb_iseq_t *base_iseq = ((((reg_cfp)))->iseq);
escape_cfp = reg_cfp;
while (((base_iseq)->body)->type != ISEQ_TYPE_BLOCK) {
if (((escape_cfp->iseq)->body)->type == ISEQ_TYPE_CLASS) {
escape_cfp = ((escape_cfp)+1);
ep = escape_cfp->ep;
base_iseq = escape_cfp->iseq;
}
else {
ep = VM_ENV_PREV_EP(ep);
base_iseq = ((base_iseq)->body)->parent_iseq;
escape_cfp = rb_vm_search_cf_from_ep(ec, escape_cfp, ep);
((void)0);
}
}
if (VM_FRAME_LAMBDA_P(escape_cfp)) {
is_orphan = 0;
state = RUBY_TAG_RETURN;
}
else {
ep = VM_ENV_PREV_EP(ep);
while (escape_cfp < eocfp) {
if (escape_cfp->ep == ep) {
const rb_iseq_t *const iseq = escape_cfp->iseq;
const VALUE epc = escape_cfp->pc - ((iseq)->body)->iseq_encoded;
const struct iseq_catch_table *const ct = ((iseq)->body)->catch_table;
unsigned int i;
if (!ct) break;
for (i=0; i < ct->size; i++) {
const struct iseq_catch_table_entry *const entry =
(&(ct)->entries[i]);
if (entry->type == CATCH_TYPE_BREAK &&
entry->iseq == base_iseq &&
entry->start < epc && entry->end >= epc) {
if (entry->cont == epc) {
is_orphan = 0;
}
break;
}
}
break;
}
escape_cfp = ((escape_cfp)+1);
}
}
if (is_orphan) {
rb_vm_localjump_error("break from proc-closure", throwobj, RUBY_TAG_BREAK);
}
}
else if (state == RUBY_TAG_RETRY) {
const VALUE *ep = VM_ENV_PREV_EP(((((reg_cfp)->ep))));
escape_cfp = rb_vm_search_cf_from_ep(ec, reg_cfp, ep);
}
else if (state == RUBY_TAG_RETURN) {
const VALUE *current_ep = ((((reg_cfp)->ep)));
const VALUE *target_ep = ((void *)0), *target_lep, *ep = current_ep;
int in_class_frame = 0;
int toplevel = 1;
escape_cfp = reg_cfp;
while (!VM_ENV_LOCAL_P(ep)) {
if (VM_ENV_FLAGS(ep, VM_FRAME_FLAG_LAMBDA) && target_ep == ((void *)0)) {
target_ep = ep;
}
ep = VM_ENV_PREV_EP(ep);
}
target_lep = ep;
while (escape_cfp < eocfp) {
const VALUE *lep = VM_CF_LEP(escape_cfp);
if (!target_lep) {
target_lep = lep;
}
if (lep == target_lep &&
VM_FRAME_RUBYFRAME_P(escape_cfp) &&
((escape_cfp->iseq)->body)->type == ISEQ_TYPE_CLASS) {
in_class_frame = 1;
target_lep = 0;
}
if (lep == target_lep) {
if (VM_FRAME_LAMBDA_P(escape_cfp)) {
toplevel = 0;
if (in_class_frame) {
goto valid_return;
}
else {
const VALUE *tep = current_ep;
while (target_lep != tep) {
if (escape_cfp->ep == tep) {
if (tep == target_ep) {
goto valid_return;
}
else {
goto unexpected_return;
}
}
tep = VM_ENV_PREV_EP(tep);
}
}
}
else if (VM_FRAME_RUBYFRAME_P(escape_cfp)) {
switch (((escape_cfp->iseq)->body)->type) {
case ISEQ_TYPE_TOP:
case ISEQ_TYPE_MAIN:
if (toplevel) {
if (in_class_frame) goto unexpected_return;
if (target_ep == ((void *)0)) {
goto valid_return;
}
else {
goto unexpected_return;
}
}
break;
case ISEQ_TYPE_EVAL:
case ISEQ_TYPE_CLASS:
toplevel = 0;
break;
default:
break;
}
}
}
if (escape_cfp->ep == target_lep && ((escape_cfp->iseq)->body)->type == ISEQ_TYPE_METHOD) {
if (target_ep == ((void *)0)) {
goto valid_return;
}
else {
goto unexpected_return;
}
}
escape_cfp = ((escape_cfp)+1);
}
unexpected_return:;
rb_vm_localjump_error("unexpected return", throwobj, RUBY_TAG_RETURN);
valid_return:;
}
else {
rb_bug("isns(throw): unsupported throw type");
}
ec->tag->state = state;
return (VALUE)THROW_DATA_NEW(throwobj, escape_cfp, state);
}
static VALUE
vm_throw(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
rb_num_t throw_state, VALUE throwobj)
{
const int state = (int)(throw_state & VM_THROW_STATE_MASK);
const int flag = (int)(throw_state & VM_THROW_NO_ESCAPE_FLAG);
if (state != 0) {
return vm_throw_start(ec, reg_cfp, state, flag, throwobj);
}
else {
return vm_throw_continue(ec, throwobj);
}
}
static inline void
vm_expandarray(VALUE *sp, VALUE ary, rb_num_t num, int flag)
{
int is_splat = flag & 0x01;
rb_num_t space_size = num + is_splat;
VALUE *base = sp - 1;
const VALUE *ptr;
rb_num_t len;
const VALUE obj = ary;
if (!RB_TYPE_P(ary, RUBY_T_ARRAY) && RB_NIL_P(ary = rb_check_array_type(ary))) {
ary = obj;
ptr = &ary;
len = 1;
}
else {
ptr = rb_array_const_ptr_transient(ary);
len = (rb_num_t)rb_array_len(ary);
}
if (space_size == 0) {
}
else if (flag & 0x02) {
rb_num_t i = 0, j;
if (len < num) {
for (i=0; i<num-len; i++) {
*base++ = ((VALUE)RUBY_Qnil);
}
}
for (j=0; i<num; i++, j++) {
VALUE v = ptr[len - j - 1];
*base++ = v;
}
if (is_splat) {
*base = rb_ary_new_from_values(len - j, ptr);
}
}
else {
rb_num_t i;
VALUE *bptr = &base[space_size - 1];
for (i=0; i<num; i++) {
if (len <= i) {
for (; i<num; i++) {
*bptr-- = ((VALUE)RUBY_Qnil);
}
break;
}
*bptr-- = ptr[i];
}
if (is_splat) {
if (num > len) {
*bptr = rb_ary_new();
}
else {
*bptr = rb_ary_new_from_values(len - num, ptr + num);
}
}
}
(*__extension__ ({ volatile VALUE *rb_gc_guarded_ptr = &(ary); __asm__("" : : "m"(rb_gc_guarded_ptr)); rb_gc_guarded_ptr; }));
}
static VALUE vm_call_general(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling);
static VALUE vm_mtbl_dump(VALUE klass, ID target_mid);
static struct rb_class_cc_entries *
vm_ccs_create(VALUE klass, struct rb_id_table *cc_tbl, ID mid, const rb_callable_method_entry_t *cme)
{
struct rb_class_cc_entries *ccs = ((struct rb_class_cc_entries *)ruby_xmalloc(sizeof(struct rb_class_cc_entries)));
ccs->capa = 0;
ccs->len = 0;
ccs->cme = cme;
(((rb_callable_method_entry_t *)cme)->flags |= ((VALUE)RUBY_FL_USER8));
ccs->entries = ((void *)0);
rb_id_table_insert(cc_tbl, mid, (VALUE)ccs);
(rb_obj_written((VALUE)(klass), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(cme), "./vm_insnhelper.c", 1913));
return ccs;
}
static void
vm_ccs_push(VALUE klass, struct rb_class_cc_entries *ccs, const struct rb_callinfo *ci, const struct rb_callcache *cc)
{
if (! vm_cc_markable(cc)) {
return;
}
else if (! vm_ci_markable(ci)) {
return;
}
if ((__builtin_expect(!!(ccs->len == ccs->capa), 0))) {
if (ccs->capa == 0) {
ccs->capa = 1;
ccs->entries = ((struct rb_class_cc_entries_entry *)ruby_xmalloc2((ccs->capa), sizeof(struct rb_class_cc_entries_entry)));
}
else {
ccs->capa *= 2;
((ccs->entries) = ((struct rb_class_cc_entries_entry *)ruby_xrealloc2((void *)(ccs->entries), (ccs->capa), sizeof(struct rb_class_cc_entries_entry))));
}
}
((void)0);
const int pos = ccs->len++;
rb_obj_write((VALUE)(klass), ((VALUE *)(&ccs->entries[pos].ci)), (VALUE)(ci), "./vm_insnhelper.c", 1940);
rb_obj_write((VALUE)(klass), ((VALUE *)(&ccs->entries[pos].cc)), (VALUE)(cc), "./vm_insnhelper.c", 1941);
if (0) {
}
}
static const struct rb_callcache *
vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
{
const struct rb_callcache *cc = rb_vm_search_method_slowpath(cd->ci, klass);
cd->cc = cc;
const struct rb_callcache *empty_cc =
rb_vm_empty_cc();
if (cd_owner && cc != empty_cc) (rb_obj_written((VALUE)(cd_owner), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(cc), "./vm_insnhelper.c", 2122));
((void)0);
return cc;
}
static const struct rb_callcache *
vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
{
const struct rb_callcache *cc = cd->cc;
if ((__builtin_expect(!!(vm_cc_class_check(cc, klass)), 1))) {
if ((__builtin_expect(!!(!((vm_cc_cme(cc))->flags & ((VALUE)RUBY_FL_USER9))), 1))) {
((void)0);
((void)0);
((void)0);
return cc;
}
((void)0);
}
else {
((void)0);
}
return vm_search_method_slowpath0(cd_owner, cd, klass);
}
static const struct rb_callcache *
vm_search_method(VALUE cd_owner, struct rb_call_data *cd, VALUE recv)
{
VALUE klass = rb_class_of(recv);
((void)0);
((void)0);
return vm_search_method_fastpath(cd_owner, cd, klass);
}
typedef union {
VALUE (*anyargs)();
VALUE (*f00)(VALUE);
VALUE (*f01)(VALUE, VALUE);
VALUE (*f02)(VALUE, VALUE, VALUE);
VALUE (*f03)(VALUE, VALUE, VALUE, VALUE);
VALUE (*f04)(VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f05)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f06)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f07)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f08)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f09)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f10)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f11)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f12)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f13)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f14)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*f15)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
VALUE (*fm1)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE);
} __attribute__((__transparent_union__)) cfunc_type;
static inline int
check_cfunc(const rb_callable_method_entry_t *me, cfunc_type func)
{
if (! me) {
return 0;
}
else {
((void)0);
((void)0);
((void)0);
if (me->def->type != VM_METHOD_TYPE_CFUNC) {
return 0;
}
else {
return me->def->body.cfunc.func == func.anyargs;
}
}
}
static inline int
vm_method_cfunc_is(const rb_iseq_t *iseq, CALL_DATA cd, VALUE recv, cfunc_type func)
{
((void)0);
const struct rb_callcache *cc = vm_search_method((VALUE)iseq, cd, recv);
return check_cfunc(vm_cc_cme(cc), func);
}
static inline _Bool
FIXNUM_2_P(VALUE a, VALUE b)
{
long x = a;
long y = b;
long z = x & y & 1;
return z == 1;
}
static inline _Bool
FLONUM_2_P(VALUE a, VALUE b)
{
long x = a;
long y = b;
long z = ((x ^ 2) | (y ^ 2)) & 3;
return !z;
}
static VALUE
opt_equality_specialized(VALUE recv, VALUE obj)
{
if (FIXNUM_2_P(recv, obj) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQ)]&((1 << 0))) == 0), 1)))) {
goto compare_by_identity;
}
else if (FLONUM_2_P(recv, obj) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQ)]&((1 << 1))) == 0), 1)))) {
goto compare_by_identity;
}
else if (RB_STATIC_SYM_P(recv) && RB_STATIC_SYM_P(obj) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQ)]&((1 << 6))) == 0), 1)))) {
goto compare_by_identity;
}
else if (RB_SPECIAL_CONST_P(recv)) {
}
else if (RBASIC_CLASS(recv) == rb_cFloat && RB_FLOAT_TYPE_P(obj) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQ)]&((1 << 1))) == 0), 1)))) {
double a = rb_float_value_inline(recv);
double b = rb_float_value_inline(obj);
return ((a == b) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (RBASIC_CLASS(recv) == rb_cString && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQ)]&((1 << 2))) == 0), 1)))) {
if (recv == obj) {
return ((VALUE)RUBY_Qtrue);
}
else if (RB_TYPE_P(obj, RUBY_T_STRING)) {
return rb_str_eql_internal(obj, recv);
}
}
return ((VALUE)RUBY_Qundef);
compare_by_identity:
return ((recv == obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
static VALUE
opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
{
((void)0);
VALUE val = opt_equality_specialized(recv, obj);
if (!RB_UNDEF_P(val)) return val;
if (!vm_method_cfunc_is(cd_owner, cd, recv, rb_obj_equal)) {
return ((VALUE)RUBY_Qundef);
}
else {
return ((recv == obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
}
extern VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE, ID, int, const VALUE*, const rb_callable_method_entry_t *, int kw_splat);
extern VALUE rb_vm_call_with_refinements(rb_execution_context_t *, VALUE, ID, int, const VALUE *, int);
static VALUE
check_match(rb_execution_context_t *ec, VALUE pattern, VALUE target, enum vm_check_match_type type)
{
switch (type) {
case VM_CHECKMATCH_TYPE_WHEN:
return pattern;
case VM_CHECKMATCH_TYPE_RESCUE:
if (!rb_obj_is_kind_of(pattern, rb_cModule)) {
rb_raise(rb_eTypeError, "class or module required for rescue clause");
}
case VM_CHECKMATCH_TYPE_CASE: {
return rb_vm_call_with_refinements(ec, pattern, idEqq, 1, &target, 0);
}
default:
rb_bug("check_match: unreachable");
}
}
static inline VALUE
double_cmp_lt(double a, double b)
{
;
return ((a < b) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
static inline VALUE
double_cmp_le(double a, double b)
{
;
return ((a <= b) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
static inline VALUE
double_cmp_gt(double a, double b)
{
;
return ((a > b) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
static inline VALUE
double_cmp_ge(double a, double b)
{
;
return ((a >= b) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
static inline VALUE *
vm_base_ptr(const rb_control_frame_t *cfp)
{
return cfp->__bp__;
}
__attribute__((__noreturn__)) static void raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc);
__attribute__((__noreturn__)) static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc);
__attribute__((__noreturn__)) static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys);
VALUE rb_keyword_error_new(const char *error, VALUE keys);
static VALUE method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VALUE *argv,
enum method_missing_reason call_status, int kw_splat);
__attribute__ ((__visibility__("default"))) extern
const rb_callable_method_entry_t *rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
struct args_info {
VALUE *argv;
int argc;
int rest_index;
int rest_dupped;
const struct rb_callinfo_kwarg *kw_arg;
VALUE *kw_argv;
VALUE rest;
};
enum arg_setup_type {
arg_setup_method,
arg_setup_block
};
static inline void
arg_rest_dup(struct args_info *args)
{
if (!args->rest_dupped) {
args->rest = rb_ary_dup(args->rest);
args->rest_dupped = 1;
}
}
static inline int
args_argc(struct args_info *args)
{
if (args->rest == ((VALUE)RUBY_Qfalse)) {
return args->argc;
}
else {
return args->argc + RARRAY_LENINT(args->rest) - args->rest_index;
}
}
static inline void
args_extend(struct args_info *args, const int min_argc)
{
int i;
if (args->rest) {
arg_rest_dup(args);
((void)0);
for (i=args->argc + RARRAY_LENINT(args->rest); i<min_argc; i++) {
rb_ary_push(args->rest, ((VALUE)RUBY_Qnil));
}
}
else {
for (i=args->argc; i<min_argc; i++) {
args->argv[args->argc++] = ((VALUE)RUBY_Qnil);
}
}
}
static inline void
args_reduce(struct args_info *args, int over_argc)
{
if (args->rest) {
const long len = rb_array_len(args->rest);
if (len > over_argc) {
arg_rest_dup(args);
rb_ary_resize(args->rest, len - over_argc);
return;
}
else {
args->rest = ((VALUE)RUBY_Qfalse);
over_argc -= len;
}
}
((void)0);
args->argc -= over_argc;
}
static inline int
args_check_block_arg0(struct args_info *args)
{
VALUE ary = ((VALUE)RUBY_Qnil);
if (args->rest && rb_array_len(args->rest) == 1) {
VALUE arg0 = RARRAY_AREF(args->rest, 0);
ary = rb_check_array_type(arg0);
}
else if (args->argc == 1) {
VALUE arg0 = args->argv[0];
ary = rb_check_array_type(arg0);
args->argv[0] = arg0;
}
if (!RB_NIL_P(ary)) {
args->rest = ary;
args->rest_index = 0;
args->argc = 0;
return 1;
}
return 0;
}
static inline void
args_copy(struct args_info *args)
{
if (args->rest != ((VALUE)RUBY_Qfalse)) {
int argc = args->argc;
args->argc = 0;
arg_rest_dup(args);
while (args->rest_index > 0 && argc > 0) {
RARRAY_ASET(args->rest, --args->rest_index, args->argv[--argc]);
}
while (argc > 0) {
rb_ary_unshift(args->rest, args->argv[--argc]);
}
}
else if (args->argc > 0) {
args->rest = rb_ary_new_from_values(args->argc, args->argv);
args->rest_index = 0;
args->rest_dupped = 1;
args->argc = 0;
}
}
static inline const VALUE *
args_rest_argv(struct args_info *args)
{
return rb_array_const_ptr_transient(args->rest) + args->rest_index;
}
static inline VALUE
args_rest_array(struct args_info *args)
{
VALUE ary;
if (args->rest) {
ary = rb_ary_behead(args->rest, args->rest_index);
args->rest_index = 0;
args->rest = 0;
}
else {
ary = rb_ary_new();
}
return ary;
}
static int
args_kw_argv_to_hash(struct args_info *args)
{
const struct rb_callinfo_kwarg *kw_arg = args->kw_arg;
const VALUE *const passed_keywords = kw_arg->keywords;
const int kw_len = kw_arg->keyword_len;
VALUE h = rb_hash_new_with_size(kw_len);
const int kw_start = args->argc - kw_len;
const VALUE * const kw_argv = args->argv + kw_start;
int i;
args->argc = kw_start + 1;
for (i=0; i<kw_len; i++) {
rb_hash_aset(h, passed_keywords[i], kw_argv[i]);
}
args->argv[args->argc - 1] = h;
return args->argc;
}
static inline void
args_setup_lead_parameters(struct args_info *args, int argc, VALUE *locals)
{
if (args->argc >= argc) {
args->argc -= argc;
args->argv += argc;
}
else {
int i, j;
const VALUE *argv = args_rest_argv(args);
for (i=args->argc, j=0; i<argc; i++, j++) {
locals[i] = argv[j];
}
args->rest_index += argc - args->argc;
args->argc = 0;
}
}
static inline void
args_setup_post_parameters(struct args_info *args, int argc, VALUE *locals)
{
long len;
len = rb_array_len(args->rest);
ruby_nonempty_memcpy((locals), (rb_array_const_ptr_transient(args->rest) + len - argc), rbimpl_size_mul_or_raise(sizeof(VALUE), (argc)));
rb_ary_resize(args->rest, len - argc);
}
static inline int
args_setup_opt_parameters(struct args_info *args, int opt_max, VALUE *locals)
{
int i;
if (args->argc >= opt_max) {
args->argc -= opt_max;
args->argv += opt_max;
i = opt_max;
}
else {
int j;
i = args->argc;
args->argc = 0;
if (args->rest) {
int len = RARRAY_LENINT(args->rest);
const VALUE *argv = rb_array_const_ptr_transient(args->rest);
for (; i<opt_max && args->rest_index < len; i++, args->rest_index++) {
locals[i] = argv[args->rest_index];
}
}
for (j=i; j<opt_max; j++) {
locals[j] = ((VALUE)RUBY_Qnil);
}
}
return i;
}
static inline void
args_setup_rest_parameter(struct args_info *args, VALUE *locals)
{
*locals = args_rest_array(args);
}
static VALUE
make_unknown_kw_hash(const VALUE *passed_keywords, int passed_keyword_len, const VALUE *kw_argv)
{
int i;
VALUE obj = rb_ary_hidden_new(1);
for (i=0; i<passed_keyword_len; i++) {
if (!RB_UNDEF_P(kw_argv[i])) {
rb_ary_push(obj, passed_keywords[i]);
}
}
return obj;
}
static VALUE
make_rest_kw_hash(const VALUE *passed_keywords, int passed_keyword_len, const VALUE *kw_argv)
{
int i;
VALUE obj = rb_hash_new_with_size(passed_keyword_len);
for (i=0; i<passed_keyword_len; i++) {
if (!RB_UNDEF_P(kw_argv[i])) {
rb_hash_aset(obj, passed_keywords[i], kw_argv[i]);
}
}
return obj;
}
static inline int
args_setup_kw_parameters_lookup(const ID key, VALUE *ptr, const VALUE *const passed_keywords, VALUE *passed_values, const int passed_keyword_len)
{
int i;
const VALUE keyname = rb_id2sym(key);
for (i=0; i<passed_keyword_len; i++) {
if (keyname == passed_keywords[i]) {
*ptr = passed_values[i];
passed_values[i] = ((VALUE)RUBY_Qundef);
return 1;
}
}
return 0;
}
static void
args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *const iseq,
VALUE *const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
VALUE *const locals)
{
const ID *acceptable_keywords = ((iseq)->body)->param.keyword->table;
const int req_key_num = ((iseq)->body)->param.keyword->required_num;
const int key_num = ((iseq)->body)->param.keyword->num;
const VALUE * const default_values = ((iseq)->body)->param.keyword->default_values;
VALUE missing = 0;
int i, di, found = 0;
int unspecified_bits = 0;
VALUE unspecified_bits_value = ((VALUE)RUBY_Qnil);
for (i=0; i<req_key_num; i++) {
ID key = acceptable_keywords[i];
if (args_setup_kw_parameters_lookup(key, &locals[i], passed_keywords, passed_values, passed_keyword_len)) {
found++;
}
else {
if (!missing) missing = rb_ary_hidden_new(1);
rb_ary_push(missing, rb_id2sym(key));
}
}
if (missing) argument_kw_error(ec, iseq, "missing", missing);
for (di=0; i<key_num; i++, di++) {
if (args_setup_kw_parameters_lookup(acceptable_keywords[i], &locals[i], passed_keywords, passed_values, passed_keyword_len)) {
found++;
}
else {
if (RB_UNDEF_P(default_values[di])) {
locals[i] = ((VALUE)RUBY_Qnil);
if ((__builtin_expect(!!(i < (32-1)), 1))) {
unspecified_bits |= 0x01 << di;
}
else {
if (RB_NIL_P(unspecified_bits_value)) {
int j;
unspecified_bits_value = rb_hash_new();
for (j=0; j<(32-1); j++) {
if (unspecified_bits & (0x01 << j)) {
rb_hash_aset(unspecified_bits_value, __builtin_choose_expr( __builtin_constant_p(j), ((VALUE)(j)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(j)), ((VALUE)RUBY_Qtrue));
}
}
}
rb_hash_aset(unspecified_bits_value, __builtin_choose_expr( __builtin_constant_p(di), ((VALUE)(di)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(di)), ((VALUE)RUBY_Qtrue));
}
}
else {
locals[i] = default_values[di];
}
}
}
if (((iseq)->body)->param.flags.has_kwrest) {
const int rest_hash_index = key_num + 1;
locals[rest_hash_index] = make_rest_kw_hash(passed_keywords, passed_keyword_len, passed_values);
}
else {
if (found != passed_keyword_len) {
VALUE keys = make_unknown_kw_hash(passed_keywords, passed_keyword_len, passed_values);
argument_kw_error(ec, iseq, "unknown", keys);
}
}
if (RB_NIL_P(unspecified_bits_value)) {
unspecified_bits_value = __builtin_choose_expr( __builtin_constant_p(unspecified_bits), ((VALUE)(unspecified_bits)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(unspecified_bits));
}
locals[key_num] = unspecified_bits_value;
}
static inline void
args_setup_kw_rest_parameter(VALUE keyword_hash, VALUE *locals, int kw_flag)
{
if (RB_NIL_P(keyword_hash)) {
keyword_hash = rb_hash_new();
}
else if (!(kw_flag & (0x01 << VM_CALL_KW_SPLAT_MUT_bit))) {
keyword_hash = rb_hash_dup(keyword_hash);
}
locals[0] = keyword_hash;
}
static inline void
args_setup_block_parameter(const rb_execution_context_t *ec, struct rb_calling_info *calling, VALUE *locals)
{
VALUE block_handler = calling->block_handler;
*locals = rb_vm_bh_to_procval(ec, block_handler);
}
struct fill_values_arg {
VALUE *keys;
VALUE *vals;
int argc;
};
static int
fill_keys_values(st_data_t key, st_data_t val, st_data_t ptr)
{
struct fill_values_arg *arg = (struct fill_values_arg *)ptr;
int i = arg->argc++;
arg->keys[i] = (VALUE)key;
arg->vals[i] = (VALUE)val;
return ST_CONTINUE;
}
static inline int
ignore_keyword_hash_p(VALUE keyword_hash, const rb_iseq_t * const iseq, unsigned int * kw_flag, VALUE * converted_keyword_hash)
{
if (!RB_TYPE_P(keyword_hash, RUBY_T_HASH)) {
keyword_hash = rb_to_hash_type(keyword_hash);
}
if (!(*kw_flag & (0x01 << VM_CALL_KW_SPLAT_MUT_bit)) &&
(((iseq)->body)->param.flags.has_kwrest ||
((iseq)->body)->param.flags.ruby2_keywords)) {
*kw_flag |= (0x01 << VM_CALL_KW_SPLAT_MUT_bit);
keyword_hash = rb_hash_dup(keyword_hash);
}
*converted_keyword_hash = keyword_hash;
return !(((iseq)->body)->param.flags.has_kw) &&
!(((iseq)->body)->param.flags.has_kwrest) &&
RHASH_EMPTY_P(keyword_hash);
}
COLDFUNC static int
setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * const iseq,
struct rb_calling_info *const calling,
const struct rb_callinfo *ci,
VALUE * const locals, const enum arg_setup_type arg_setup_type) {
const int min_argc = ((iseq)->body)->param.lead_num + ((iseq)->body)->param.post_num;
const int max_argc = (((iseq)->body)->param.flags.has_rest == 0) ? min_argc + ((iseq)->body)->param.opt_num : (-1);
int given_argc;
unsigned int kw_flag = vm_ci_flag(ci) & ((0x01 << VM_CALL_KWARG_bit) | (0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_MUT_bit));
int opt_pc = 0, allow_autosplat = !kw_flag;
struct args_info args_body, *args;
VALUE keyword_hash = ((VALUE)RUBY_Qnil);
VALUE * const orig_sp = ec->cfp->sp;
unsigned int i;
VALUE flag_keyword_hash = 0;
VALUE splat_flagged_keyword_hash = 0;
VALUE converted_keyword_hash = 0;
VALUE rest_last = 0;
;
for (i=calling->argc; i<((iseq)->body)->param.size; i++) {
locals[i] = ((VALUE)RUBY_Qnil);
}
ec->cfp->sp = &locals[i];
args = &args_body;
given_argc = args->argc = calling->argc;
args->argv = locals;
args->rest_dupped = 0;
if (kw_flag & (0x01 << VM_CALL_KWARG_bit)) {
args->kw_arg = vm_ci_kwarg(ci);
if (((iseq)->body)->param.flags.has_kw) {
int kw_len = args->kw_arg->keyword_len;
args->kw_argv = ((VALUE *)__builtin_alloca (rbimpl_size_mul_or_raise(sizeof(VALUE), (kw_len))));
args->argc -= kw_len;
given_argc -= kw_len;
ruby_nonempty_memcpy((args->kw_argv), (locals + args->argc), rbimpl_size_mul_or_raise(sizeof(VALUE), (kw_len)));
}
else {
args->kw_argv = ((void *)0);
given_argc = args_kw_argv_to_hash(args);
kw_flag |= (0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_MUT_bit);
}
}
else {
args->kw_arg = ((void *)0);
args->kw_argv = ((void *)0);
}
if (vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit)) {
int len;
args->rest = locals[--args->argc];
args->rest_index = 0;
len = RARRAY_LENINT(args->rest);
given_argc += len - 1;
rest_last = RARRAY_AREF(args->rest, len - 1);
if (!kw_flag && len > 0) {
if (RB_TYPE_P(rest_last, RUBY_T_HASH) &&
(((struct RHash *)rest_last)->basic.flags & RHASH_PASS_AS_KEYWORDS)) {
splat_flagged_keyword_hash = rest_last;
rest_last = rb_hash_dup(rest_last);
kw_flag |= (0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_MUT_bit);
}
else {
rest_last = 0;
}
}
if (kw_flag & (0x01 << VM_CALL_KW_SPLAT_bit)) {
if (ignore_keyword_hash_p(rest_last, iseq, &kw_flag, &converted_keyword_hash)) {
arg_rest_dup(args);
rb_ary_pop(args->rest);
given_argc--;
kw_flag &= ~((0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_MUT_bit));
}
else {
if (rest_last != converted_keyword_hash) {
rest_last = converted_keyword_hash;
arg_rest_dup(args);
RARRAY_ASET(args->rest, len - 1, rest_last);
}
if (((iseq)->body)->param.flags.ruby2_keywords && rest_last) {
flag_keyword_hash = rest_last;
}
else if (((iseq)->body)->param.flags.has_kw || ((iseq)->body)->param.flags.has_kwrest) {
arg_rest_dup(args);
rb_ary_pop(args->rest);
given_argc--;
keyword_hash = rest_last;
}
}
}
}
else {
if (kw_flag & (0x01 << VM_CALL_KW_SPLAT_bit)) {
VALUE last_arg = args->argv[args->argc-1];
if (ignore_keyword_hash_p(last_arg, iseq, &kw_flag, &converted_keyword_hash)) {
args->argc--;
given_argc--;
kw_flag &= ~((0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_MUT_bit));
}
else {
if (last_arg != converted_keyword_hash) {
last_arg = converted_keyword_hash;
args->argv[args->argc-1] = last_arg;
}
if (((iseq)->body)->param.flags.ruby2_keywords) {
flag_keyword_hash = last_arg;
}
else if (((iseq)->body)->param.flags.has_kw || ((iseq)->body)->param.flags.has_kwrest) {
args->argc--;
given_argc--;
keyword_hash = last_arg;
}
}
}
args->rest = ((VALUE)RUBY_Qfalse);
}
if (flag_keyword_hash && RB_TYPE_P(flag_keyword_hash, RUBY_T_HASH)) {
((struct RHash *)flag_keyword_hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
}
if (kw_flag && ((iseq)->body)->param.flags.accepts_no_kwarg) {
rb_raise(rb_eArgError, "no keywords accepted");
}
switch (arg_setup_type) {
case arg_setup_method:
break;
case arg_setup_block:
if (given_argc == 1 &&
allow_autosplat &&
!splat_flagged_keyword_hash &&
(min_argc > 0 || ((iseq)->body)->param.opt_num > 1) &&
!((iseq)->body)->param.flags.ambiguous_param0 &&
!((((iseq)->body)->param.flags.has_kw ||
((iseq)->body)->param.flags.has_kwrest)
&& max_argc == 1) &&
args_check_block_arg0(args)) {
given_argc = RARRAY_LENINT(args->rest);
}
break;
}
if (given_argc < min_argc) {
if (arg_setup_type == arg_setup_block) {
do { __extension__ _Static_assert(sizeof(*((ec->cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((ec->cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((ec->cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((ec->cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((ec->cfp)->sp)[((min_argc))]; if ((__builtin_expect(!!(((ec->cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
given_argc = min_argc;
args_extend(args, min_argc);
}
else {
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
}
}
if (given_argc > max_argc && max_argc != (-1)) {
if (arg_setup_type == arg_setup_block) {
args_reduce(args, given_argc - max_argc);
given_argc = max_argc;
}
else {
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
}
}
if (((iseq)->body)->param.flags.has_lead) {
args_setup_lead_parameters(args, ((iseq)->body)->param.lead_num, locals + 0);
}
if (((iseq)->body)->param.flags.has_rest || ((iseq)->body)->param.flags.has_post){
args_copy(args);
}
if (((iseq)->body)->param.flags.has_post) {
args_setup_post_parameters(args, ((iseq)->body)->param.post_num, locals + ((iseq)->body)->param.post_start);
}
if (((iseq)->body)->param.flags.has_opt) {
int opt = args_setup_opt_parameters(args, ((iseq)->body)->param.opt_num, locals + ((iseq)->body)->param.lead_num);
opt_pc = (int)((iseq)->body)->param.opt_table[opt];
}
if (((iseq)->body)->param.flags.has_rest) {
args_setup_rest_parameter(args, locals + ((iseq)->body)->param.rest_start);
VALUE ary = *(locals + ((iseq)->body)->param.rest_start);
VALUE index = rb_array_len(ary) - 1;
if (splat_flagged_keyword_hash &&
!((iseq)->body)->param.flags.ruby2_keywords &&
!((iseq)->body)->param.flags.has_kw &&
!((iseq)->body)->param.flags.has_kwrest &&
RARRAY_AREF(ary, index) == splat_flagged_keyword_hash) {
((struct RHash *)rest_last)->basic.flags &= ~RHASH_PASS_AS_KEYWORDS;
RARRAY_ASET(ary, index, rest_last);
}
}
if (((iseq)->body)->param.flags.has_kw) {
VALUE * const klocals = locals + ((iseq)->body)->param.keyword->bits_start - ((iseq)->body)->param.keyword->num;
if (args->kw_argv != ((void *)0)) {
const struct rb_callinfo_kwarg *kw_arg = args->kw_arg;
args_setup_kw_parameters(ec, iseq, args->kw_argv, kw_arg->keyword_len, kw_arg->keywords, klocals);
}
else if (!RB_NIL_P(keyword_hash)) {
int kw_len = rb_long2int_inline(RHASH_SIZE(keyword_hash));
struct fill_values_arg arg;
arg.keys = args->kw_argv = ((VALUE *)__builtin_alloca (rbimpl_size_mul_or_raise(sizeof(VALUE), (kw_len * 2))));
arg.vals = arg.keys + kw_len;
arg.argc = 0;
rb_hash_foreach(keyword_hash, fill_keys_values, (VALUE)&arg);
((void)0);
args_setup_kw_parameters(ec, iseq, arg.vals, kw_len, arg.keys, klocals);
}
else {
((void)0);
args_setup_kw_parameters(ec, iseq, ((void *)0), 0, ((void *)0), klocals);
}
}
else if (((iseq)->body)->param.flags.has_kwrest) {
args_setup_kw_rest_parameter(keyword_hash, locals + ((iseq)->body)->param.keyword->rest_start, kw_flag);
}
else if (!RB_NIL_P(keyword_hash) && RHASH_SIZE(keyword_hash) > 0 && arg_setup_type == arg_setup_method) {
argument_kw_error(ec, iseq, "unknown", rb_hash_keys(keyword_hash));
}
if (((iseq)->body)->param.flags.has_block) {
if (((iseq)->body)->local_iseq == iseq) {
}
else {
args_setup_block_parameter(ec, calling, locals + ((iseq)->body)->param.block_start);
}
}
ec->cfp->sp = orig_sp;
return opt_pc;
}
static void
raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc)
{
VALUE at;
if (iseq) {
vm_push_frame(ec, iseq, VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL, ((VALUE)RUBY_Qnil) ,
0 , ((VALUE)RUBY_Qfalse) ,
((iseq)->body)->iseq_encoded,
ec->cfp->sp, 0, 0 );
at = rb_ec_backtrace_object(ec);
rb_backtrace_use_iseq_first_lineno_for_last_location(at);
rb_vm_pop_frame(ec);
}
else {
at = rb_ec_backtrace_object(ec);
}
rb_ivar_set(exc, idBt_locations, at);
rb_exc_set_backtrace(exc, at);
rb_exc_raise(exc);
}
static void
argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
{
VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
if (((iseq)->body)->param.flags.has_kw) {
const struct rb_iseq_param_keyword *const kw = ((iseq)->body)->param.keyword;
const ID *keywords = kw->table;
int req_key_num = kw->required_num;
if (req_key_num > 0) {
static const char required[] = "; required keywords";
VALUE mesg = rb_attr_get(exc, idMesg);
rb_str_resize(mesg, RSTRING_LEN(mesg)-1);
rb_str_cat(mesg, required, sizeof(required) - 1 - (req_key_num == 1));
((__builtin_constant_p(":") ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((mesg), (":")));
do {
((__builtin_constant_p(" ") ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((mesg), (" ")));
rb_str_append(mesg, rb_id2str(*keywords++));
((__builtin_constant_p(",") ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((mesg), (",")));
} while (--req_key_num);
RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
}
}
raise_argument_error(ec, iseq, exc);
}
static void
argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys)
{
raise_argument_error(ec, iseq, rb_keyword_error_new(error, keys));
}
static inline void
vm_caller_setup_arg_splat(rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
int argc = calling->argc;
VALUE *argv = cfp->sp - argc;
VALUE ary = argv[argc-1];
;
cfp->sp--;
if (!RB_NIL_P(ary)) {
const VALUE *ptr = rb_array_const_ptr_transient(ary);
long len = rb_array_len(ary), i;
do { __extension__ _Static_assert(sizeof(*((cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((cfp)->sp)[((len))]; if ((__builtin_expect(!!(((cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
for (i = 0; i < len; i++) {
*cfp->sp++ = ptr[i];
}
calling->argc += i - 1;
}
}
static inline void
vm_caller_setup_arg_kw(rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci)
{
const VALUE *const passed_keywords = vm_ci_kwarg(ci)->keywords;
const int kw_len = vm_ci_kwarg(ci)->keyword_len;
const VALUE h = rb_hash_new_with_size(kw_len);
VALUE *sp = cfp->sp;
int i;
for (i=0; i<kw_len; i++) {
rb_hash_aset(h, passed_keywords[i], (sp - kw_len)[i]);
}
(sp-kw_len)[0] = h;
cfp->sp -= kw_len - 1;
calling->argc -= kw_len - 1;
calling->kw_splat = 1;
}
static VALUE
vm_to_proc(VALUE proc)
{
if ((__builtin_expect(!!(!rb_obj_is_proc(proc)), 0))) {
VALUE b;
const rb_callable_method_entry_t *me =
rb_callable_method_entry_with_refinements(rb_class_of(proc), idTo_proc, ((void *)0));
if (me) {
b = rb_vm_call0(rb_current_execution_context(1), proc, idTo_proc, 0, ((void *)0), me, 0);
}
else {
b = rb_check_convert_type_with_id(proc, RUBY_T_DATA, "Proc", idTo_proc);
}
if (RB_NIL_P(b) || !rb_obj_is_proc(b)) {
rb_raise(rb_eTypeError,
"wrong argument type %s (expected Proc)",
rb_obj_classname(proc));
}
return b;
}
else {
return proc;
}
}
static VALUE
refine_sym_proc_call(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg)
{
VALUE obj;
ID mid;
const rb_callable_method_entry_t *me = 0;
rb_execution_context_t *ec;
const VALUE symbol = RARRAY_AREF(callback_arg, 0);
const VALUE refinements = RARRAY_AREF(callback_arg, 1);
int kw_splat = rb_keyword_given_p();
VALUE klass;
if (argc-- < 1) {
rb_raise(rb_eArgError, "no receiver given");
}
obj = *argv++;
mid = rb_sym2id(symbol);
for (klass = rb_class_of(obj); klass; klass = RCLASS_SUPER(klass)) {
me = rb_callable_method_entry(klass, mid);
if (me) {
me = rb_resolve_refined_method_callable(refinements, me);
if (me) break;
}
}
ec = rb_current_execution_context(1);
if (!RB_NIL_P(blockarg)) {
vm_passed_block_handler_set(ec, blockarg);
}
if (!me) {
return method_missing(ec, obj, mid, argc, argv, MISSING_NOENTRY, kw_splat);
}
return rb_vm_call0(ec, obj, mid, argc, argv, me, kw_splat);
}
static VALUE
vm_caller_setup_arg_block(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
const struct rb_callinfo *ci, const rb_iseq_t *blockiseq, const int is_super)
{
if (vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_BLOCKARG_bit)) {
VALUE block_code = *(--reg_cfp->sp);
if (RB_NIL_P(block_code)) {
return 0;
}
else if (block_code == rb_block_param_proxy) {
((void)0);
VALUE handler = VM_CF_BLOCK_HANDLER(reg_cfp);
reg_cfp->block_code = (const void *) handler;
return handler;
}
else if (RB_SYMBOL_P(block_code) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) {
const rb_cref_t *cref = vm_env_cref(reg_cfp->ep);
if (cref && !RB_NIL_P(cref->refinements)) {
VALUE ref = cref->refinements;
VALUE func = rb_hash_lookup(ref, block_code);
if (RB_NIL_P(func)) {
VALUE callback_arg = rb_ary_hidden_new(2);
rb_ary_push(callback_arg, block_code);
rb_ary_push(callback_arg, ref);
RB_OBJ_FREEZE_RAW(callback_arg);
func = rb_func_lambda_new(refine_sym_proc_call, callback_arg, 1, (-1));
rb_hash_aset(ref, block_code, func);
}
block_code = func;
}
return block_code;
}
else {
return vm_to_proc(block_code);
}
}
else if (blockiseq != ((void *)0)) {
struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(reg_cfp);
captured->code.iseq = blockiseq;
return VM_BH_FROM_ISEQ_BLOCK(captured);
}
else {
if (is_super) {
return ((VM_EP_LEP(((((reg_cfp)->ep)))))[(-1)]);
}
else {
return 0;
}
}
}
static inline VALUE vm_call_iseq_setup_2(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, int opt_pc, int param_size, int local_size);
__attribute__ ((__always_inline__)) static VALUE vm_call_iseq_setup_normal(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, const rb_callable_method_entry_t *me, int opt_pc, int param_size, int local_size);
static inline VALUE vm_call_iseq_setup_tailcall(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, int opt_pc);
static VALUE vm_call_super_method(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling);
static VALUE vm_call_method_nome(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling);
static VALUE vm_call_method_each_type(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling);
static inline VALUE vm_call_method(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling);
static vm_call_handler vm_call_iseq_setup_func(const struct rb_callinfo *ci, const int param_size, const int local_size);
static VALUE
vm_call_iseq_setup_tailcall_0start(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_tailcall(ec, cfp, calling, 0);
}
static VALUE
vm_call_iseq_setup_normal_0start(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
const struct rb_callcache *cc = calling->cc;
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
int param = ((iseq)->body)->param.size;
int local = ((iseq)->body)->local_table_size;
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), 0, param, local);
}
static _Bool
rb_simple_iseq_p(const rb_iseq_t *iseq)
{
return ((iseq)->body)->param.flags.has_opt == 0 &&
((iseq)->body)->param.flags.has_rest == 0 &&
((iseq)->body)->param.flags.has_post == 0 &&
((iseq)->body)->param.flags.has_kw == 0 &&
((iseq)->body)->param.flags.has_kwrest == 0 &&
((iseq)->body)->param.flags.accepts_no_kwarg == 0 &&
((iseq)->body)->param.flags.has_block == 0;
}static inline
__attribute__ ((__visibility__("default"))) _Bool
rb_iseq_only_optparam_p(const rb_iseq_t *iseq)
{
return ((iseq)->body)->param.flags.has_opt == 1 &&
((iseq)->body)->param.flags.has_rest == 0 &&
((iseq)->body)->param.flags.has_post == 0 &&
((iseq)->body)->param.flags.has_kw == 0 &&
((iseq)->body)->param.flags.has_kwrest == 0 &&
((iseq)->body)->param.flags.accepts_no_kwarg == 0 &&
((iseq)->body)->param.flags.has_block == 0;
}static inline
__attribute__ ((__visibility__("default"))) _Bool
rb_iseq_only_kwparam_p(const rb_iseq_t *iseq)
{
return ((iseq)->body)->param.flags.has_opt == 0 &&
((iseq)->body)->param.flags.has_rest == 0 &&
((iseq)->body)->param.flags.has_post == 0 &&
((iseq)->body)->param.flags.has_kw == 1 &&
((iseq)->body)->param.flags.has_kwrest == 0 &&
((iseq)->body)->param.flags.has_block == 0;
}
static _Bool
rb_splat_or_kwargs_p(const struct rb_callinfo *__restrict ci)
{
return (vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit)) || (vm_ci_flag(ci) & ((0x01 << VM_CALL_KWARG_bit) | (0x01 << VM_CALL_KW_SPLAT_bit)));
}
static inline void
CALLER_SETUP_ARG(struct rb_control_frame_struct *__restrict cfp,
struct rb_calling_info *__restrict calling,
const struct rb_callinfo *__restrict ci)
{
if ((__builtin_expect(!!((vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit))), 0))) {
VALUE final_hash;
vm_caller_setup_arg_splat(cfp, calling);
if (!(vm_ci_flag(ci) & ((0x01 << VM_CALL_KWARG_bit) | (0x01 << VM_CALL_KW_SPLAT_bit))) &&
calling->argc > 0 &&
RB_TYPE_P((final_hash = *(cfp->sp - 1)), RUBY_T_HASH) &&
(((struct RHash *)final_hash)->basic.flags & RHASH_PASS_AS_KEYWORDS)) {
*(cfp->sp - 1) = rb_hash_dup(final_hash);
calling->kw_splat = 1;
}
}
if ((__builtin_expect(!!((vm_ci_flag(ci) & ((0x01 << VM_CALL_KWARG_bit) | (0x01 << VM_CALL_KW_SPLAT_bit)))), 0))) {
if ((vm_ci_flag(ci) & (0x01 << VM_CALL_KWARG_bit))) {
vm_caller_setup_arg_kw(cfp, calling, ci);
}
else {
VALUE keyword_hash = cfp->sp[-1];
if (!RB_TYPE_P(keyword_hash, RUBY_T_HASH)) {
cfp->sp[-1] = rb_hash_dup(rb_to_hash_type(keyword_hash));
}
else if (!(vm_ci_flag(ci) & (0x01 << VM_CALL_KW_SPLAT_MUT_bit))) {
cfp->sp[-1] = rb_hash_dup(keyword_hash);
}
}
}
}
static inline void
CALLER_REMOVE_EMPTY_KW_SPLAT(struct rb_control_frame_struct *__restrict cfp,
struct rb_calling_info *__restrict calling,
const struct rb_callinfo *__restrict ci)
{
if ((__builtin_expect(!!(calling->kw_splat), 0))) {
if (RHASH_EMPTY_P(cfp->sp[-1])) {
cfp->sp--;
calling->argc--;
calling->kw_splat = 0;
}
}
}
static VALUE
vm_call_iseq_setup_normal_opt_start(rb_execution_context_t *ec, rb_control_frame_t *cfp,
struct rb_calling_info *calling)
{
const struct rb_callcache *cc = calling->cc;
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
const int lead_num = ((iseq)->body)->param.lead_num;
const int opt = calling->argc - lead_num;
const int opt_num = ((iseq)->body)->param.opt_num;
const int opt_pc = (int)((iseq)->body)->param.opt_table[opt];
const int param = ((iseq)->body)->param.size;
const int local = ((iseq)->body)->local_table_size;
const int delta = opt_num - opt;
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), opt_pc, param - delta, local);
}
static VALUE
vm_call_iseq_setup_tailcall_opt_start(rb_execution_context_t *ec, rb_control_frame_t *cfp,
struct rb_calling_info *calling)
{
const struct rb_callcache *cc = calling->cc;
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
const int lead_num = ((iseq)->body)->param.lead_num;
const int opt = calling->argc - lead_num;
const int opt_pc = (int)((iseq)->body)->param.opt_table[opt];
((void)0);
return vm_call_iseq_setup_tailcall(ec, cfp, calling, opt_pc);
}
static void
args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *const iseq,
VALUE *const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
VALUE *const locals);
static VALUE
vm_call_iseq_setup_kwparm_kwarg(rb_execution_context_t *ec, rb_control_frame_t *cfp,
struct rb_calling_info *calling)
{
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
((void)0);
((void)0);
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
const struct rb_iseq_param_keyword *kw_param = ((iseq)->body)->param.keyword;
const struct rb_callinfo_kwarg *kw_arg = vm_ci_kwarg(ci);
const int ci_kw_len = kw_arg->keyword_len;
const VALUE * const ci_keywords = kw_arg->keywords;
VALUE *argv = cfp->sp - calling->argc;
VALUE *const klocals = argv + kw_param->bits_start - kw_param->num;
const int lead_num = ((iseq)->body)->param.lead_num;
VALUE * const ci_kws = ((VALUE *)__builtin_alloca (rbimpl_size_mul_or_raise(sizeof(VALUE), (ci_kw_len))));
ruby_nonempty_memcpy((ci_kws), (argv + lead_num), rbimpl_size_mul_or_raise(sizeof(VALUE), (ci_kw_len)));
args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals);
int param = ((iseq)->body)->param.size;
int local = ((iseq)->body)->local_table_size;
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), 0, param, local);
}
static VALUE
vm_call_iseq_setup_kwparm_nokwarg(rb_execution_context_t *ec, rb_control_frame_t *cfp,
struct rb_calling_info *calling)
{
const struct rb_callinfo *__attribute__ ((__unused__)) ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
((void)0);
((void)0);
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
const struct rb_iseq_param_keyword *kw_param = ((iseq)->body)->param.keyword;
VALUE * const argv = cfp->sp - calling->argc;
VALUE * const klocals = argv + kw_param->bits_start - kw_param->num;
int i;
for (i=0; i<kw_param->num; i++) {
klocals[i] = kw_param->default_values[i];
}
klocals[i] = __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0));
int param = ((iseq)->body)->param.size;
int local = ((iseq)->body)->local_table_size;
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), 0, param, local);
}
static inline int
vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
const rb_iseq_t *iseq, VALUE *argv, int param_size, int local_size)
{
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
_Bool cacheable_ci = vm_ci_markable(ci);
if ((__builtin_expect(!!(!(vm_ci_flag(ci) & (0x01 << VM_CALL_KW_SPLAT_bit))), 1))) {
if ((__builtin_expect(!!(rb_simple_iseq_p(iseq)), 1))) {
rb_control_frame_t *cfp = ec->cfp;
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
if (calling->argc != ((iseq)->body)->param.lead_num) {
argument_arity_error(ec, iseq, calling->argc, ((iseq)->body)->param.lead_num, ((iseq)->body)->param.lead_num);
}
((void)0);
((void)0);
CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size), cacheable_ci && vm_call_iseq_optimizable_p(ci, cc));
return 0;
}
else if (rb_iseq_only_optparam_p(iseq)) {
rb_control_frame_t *cfp = ec->cfp;
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
const int lead_num = ((iseq)->body)->param.lead_num;
const int opt_num = ((iseq)->body)->param.opt_num;
const int argc = calling->argc;
const int opt = argc - lead_num;
if (opt < 0 || opt > opt_num) {
argument_arity_error(ec, iseq, argc, lead_num, lead_num + opt_num);
}
if ((__builtin_expect(!!(!(vm_ci_flag(ci) & (0x01 << VM_CALL_TAILCALL_bit))), 1))) {
CC_SET_FASTPATH(cc, vm_call_iseq_setup_normal_opt_start,
!(vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit)) && !(vm_ci_flag(ci) & (0x01 << VM_CALL_KWARG_bit)) &&
cacheable_ci && vm_call_cacheable(ci, cc));
}
else {
CC_SET_FASTPATH(cc, vm_call_iseq_setup_tailcall_opt_start,
!(vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit)) && !(vm_ci_flag(ci) & (0x01 << VM_CALL_KWARG_bit)) &&
cacheable_ci && vm_call_cacheable(ci, cc));
}
((void)0);
for (int i=argc; i<lead_num + opt_num; i++) {
argv[i] = ((VALUE)RUBY_Qnil);
}
return (int)((iseq)->body)->param.opt_table[opt];
}
else if (rb_iseq_only_kwparam_p(iseq) && !(vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SPLAT_bit))) {
const int lead_num = ((iseq)->body)->param.lead_num;
const int argc = calling->argc;
const struct rb_iseq_param_keyword *kw_param = ((iseq)->body)->param.keyword;
if (vm_ci_flag(ci) & (0x01 << VM_CALL_KWARG_bit)) {
const struct rb_callinfo_kwarg *kw_arg = vm_ci_kwarg(ci);
if (argc - kw_arg->keyword_len == lead_num) {
const int ci_kw_len = kw_arg->keyword_len;
const VALUE * const ci_keywords = kw_arg->keywords;
VALUE * const ci_kws = ((VALUE *)__builtin_alloca (rbimpl_size_mul_or_raise(sizeof(VALUE), (ci_kw_len))));
ruby_nonempty_memcpy((ci_kws), (argv + lead_num), rbimpl_size_mul_or_raise(sizeof(VALUE), (ci_kw_len)));
VALUE *const klocals = argv + kw_param->bits_start - kw_param->num;
args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals);
CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_kwarg,
cacheable_ci && vm_call_cacheable(ci, cc));
return 0;
}
}
else if (argc == lead_num) {
VALUE *const klocals = argv + kw_param->bits_start - kw_param->num;
args_setup_kw_parameters(ec, iseq, ((void *)0), 0, ((void *)0), klocals);
if (klocals[kw_param->num] == __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0))) {
CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_nokwarg,
cacheable_ci && vm_call_cacheable(ci, cc));
}
return 0;
}
}
}
return setup_parameters_complex(ec, iseq, calling, ci, argv, arg_setup_method);
}
COLDFUNC static VALUE
vm_call_iseq_setup(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling) {
((void)0);
const struct rb_callcache *cc = calling->cc;
const rb_iseq_t *iseq = def_iseq_ptr(vm_cc_cme(cc)->def);
const int param_size = ((iseq)->body)->param.size;
const int local_size = ((iseq)->body)->local_table_size;
const int opt_pc = vm_callee_setup_arg(ec, calling, def_iseq_ptr(vm_cc_cme(cc)->def), cfp->sp - calling->argc, param_size, local_size);
return vm_call_iseq_setup_2(ec, cfp, calling, opt_pc, param_size, local_size);
}
COLDFUNC static VALUE
vm_call_iseq_setup_2(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling,
int opt_pc, int param_size, int local_size) {
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
if ((__builtin_expect(!!(!(vm_ci_flag(ci) & (0x01 << VM_CALL_TAILCALL_bit))), 1))) {
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(cc), opt_pc, param_size, local_size);
}
else {
return vm_call_iseq_setup_tailcall(ec, cfp, calling, opt_pc);
}
}
static inline VALUE
vm_call_iseq_setup_normal(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, const rb_callable_method_entry_t *me,
int opt_pc, int param_size, int local_size)
{
const rb_iseq_t *iseq = def_iseq_ptr(me->def);
VALUE *argv = cfp->sp - calling->argc;
VALUE *sp = argv + param_size;
cfp->sp = argv - 1 ;
vm_push_frame(ec, iseq, VM_FRAME_MAGIC_METHOD | VM_ENV_FLAG_LOCAL, calling->recv,
calling->block_handler, (VALUE)me,
((iseq)->body)->iseq_encoded + opt_pc, sp,
local_size - param_size,
((iseq)->body)->stack_max);
return ((VALUE)RUBY_Qundef);
}
COLDFUNC static VALUE
vm_call_iseq_setup_tailcall(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, int opt_pc) {
const struct rb_callcache *cc = calling->cc;
unsigned int i;
VALUE *argv = cfp->sp - calling->argc;
const rb_callable_method_entry_t *me = vm_cc_cme(cc);
const rb_iseq_t *iseq = def_iseq_ptr(me->def);
VALUE *src_argv = argv;
VALUE *sp_orig, *sp;
VALUE finish_flag = VM_FRAME_FINISHED_P(cfp) ? VM_FRAME_FLAG_FINISH : 0;
if (VM_BH_FROM_CFP_P(calling->block_handler, cfp)) {
struct rb_captured_block *dst_captured = VM_CFP_TO_CAPTURED_BLOCK(((cfp)+1));
const struct rb_captured_block *src_captured = VM_BH_TO_CAPT_BLOCK(calling->block_handler);
dst_captured->code.val = src_captured->code.val;
if (VM_BH_ISEQ_BLOCK_P(calling->block_handler)) {
calling->block_handler = VM_BH_FROM_ISEQ_BLOCK(dst_captured);
}
else {
calling->block_handler = VM_BH_FROM_IFUNC_BLOCK(dst_captured);
}
}
vm_pop_frame(ec, cfp, cfp->ep);
cfp = ec->cfp;
sp_orig = sp = cfp->sp;
sp[0] = calling->recv;
sp++;
for (i=0; i < ((iseq)->body)->param.size; i++) {
*sp++ = src_argv[i];
}
vm_push_frame(ec, iseq, VM_FRAME_MAGIC_METHOD | VM_ENV_FLAG_LOCAL | finish_flag,
calling->recv, calling->block_handler, (VALUE)me,
((iseq)->body)->iseq_encoded + opt_pc, sp,
((iseq)->body)->local_table_size - ((iseq)->body)->param.size,
((iseq)->body)->stack_max);
cfp->sp = sp_orig;
return ((VALUE)RUBY_Qundef);
}
static void
ractor_unsafe_check(void)
{
if (!rb_ractor_main_p()) {
rb_raise(rb_eRactorUnsafeError, "ractor unsafe method called from not main ractor");
}
}
static VALUE
call_cfunc_m2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func;
return (*f)(recv, rb_ary_new_from_values(argc, argv));
}
static VALUE
call_cfunc_m1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(int, const VALUE *, VALUE) = (VALUE(*)(int, const VALUE *, VALUE))func;
return (*f)(argc, argv, recv);
}
static VALUE
call_cfunc_0(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE) = (VALUE(*)(VALUE))func;
return (*f)(recv);
}
static VALUE
call_cfunc_1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func;
return (*f)(recv, argv[0]);
}
static VALUE
call_cfunc_2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1]);
}
static VALUE
call_cfunc_3(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2]);
}
static VALUE
call_cfunc_4(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3]);
}
static VALUE
call_cfunc_5(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
static VALUE
call_cfunc_6(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}
static VALUE
call_cfunc_7(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}
static VALUE
call_cfunc_8(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}
static VALUE
call_cfunc_9(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
}
static VALUE
call_cfunc_10(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
}
static VALUE
call_cfunc_11(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
}
static VALUE
call_cfunc_12(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
}
static VALUE
call_cfunc_13(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]);
}
static VALUE
call_cfunc_14(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
}
static VALUE
call_cfunc_15(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
ractor_unsafe_check();
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]);
}
static VALUE
ractor_safe_call_cfunc_m2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func;
return (*f)(recv, rb_ary_new_from_values(argc, argv));
}
static VALUE
ractor_safe_call_cfunc_m1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(int, const VALUE *, VALUE) = (VALUE(*)(int, const VALUE *, VALUE))func;
return (*f)(argc, argv, recv);
}
static VALUE
ractor_safe_call_cfunc_0(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE) = (VALUE(*)(VALUE))func;
return (*f)(recv);
}
static VALUE
ractor_safe_call_cfunc_1(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE) = (VALUE(*)(VALUE, VALUE))func;
return (*f)(recv, argv[0]);
}
static VALUE
ractor_safe_call_cfunc_2(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1]);
}
static VALUE
ractor_safe_call_cfunc_3(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2]);
}
static VALUE
ractor_safe_call_cfunc_4(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3]);
}
static VALUE
ractor_safe_call_cfunc_5(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
static VALUE
ractor_safe_call_cfunc_6(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}
static VALUE
ractor_safe_call_cfunc_7(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}
static VALUE
ractor_safe_call_cfunc_8(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}
static VALUE
ractor_safe_call_cfunc_9(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
}
static VALUE
ractor_safe_call_cfunc_10(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
}
static VALUE
ractor_safe_call_cfunc_11(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
}
static VALUE
ractor_safe_call_cfunc_12(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
}
static VALUE
ractor_safe_call_cfunc_13(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]);
}
static VALUE
ractor_safe_call_cfunc_14(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
}
static VALUE
ractor_safe_call_cfunc_15(VALUE recv, int argc, const VALUE *argv, VALUE (*func)())
{
VALUE(*f)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE) = (VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE))func;
return (*f)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]);
}
static inline int
vm_cfp_consistent_p(rb_execution_context_t *ec, const rb_control_frame_t *reg_cfp)
{
const int ov_flags = RAISED_STACKOVERFLOW;
if ((__builtin_expect(!!(reg_cfp == ec->cfp + 1), 1))) return 1;
if ((((ec)->raised_flag & (ov_flags)) != 0)) {
((ec)->raised_flag &= ~(ov_flags));
return 1;
}
return 0;
}
static inline
const rb_method_cfunc_t *
vm_method_cfunc_entry(const rb_callable_method_entry_t *me)
{
return (&(me->def)->body.cfunc);
}
static VALUE
vm_call_cfunc_with_frame(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
VALUE val;
const rb_callable_method_entry_t *me = vm_cc_cme(cc);
const rb_method_cfunc_t *cfunc = vm_method_cfunc_entry(me);
int len = cfunc->argc;
VALUE recv = calling->recv;
VALUE block_handler = calling->block_handler;
VALUE frame_type = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
int argc = calling->argc;
int orig_argc = argc;
if ((__builtin_expect(!!(calling->kw_splat), 0))) {
frame_type |= VM_FRAME_FLAG_CFRAME_KW;
}
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, me->owner, me->def->original_id, &args)) { do {} while (0); } } } while (0);
do { const rb_event_flag_t flag_arg_ = (0x0020); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, recv, me->def->original_id, vm_ci_mid(ci), me->owner, ((VALUE)RUBY_Qundef), 0); } } while (0);
vm_push_frame(ec, ((void *)0), frame_type, recv,
block_handler, (VALUE)me,
0, ec->cfp->sp, 0, 0);
if (len >= 0) rb_check_arity(argc, len, len);
reg_cfp->sp -= orig_argc + 1;
val = (*cfunc->invoker)(recv, argc, reg_cfp->sp + 1, cfunc->func);
((__builtin_expect(!!(vm_cfp_consistent_p(ec, reg_cfp)), 1)) ? (void)0 : rb_bug("vm_call_cfunc" ": cfp consistency error (%p, %p)", (void *)reg_cfp, (void *)(ec->cfp+1)));
rb_vm_pop_frame(ec);
do { const rb_event_flag_t flag_arg_ = (0x0040); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, recv, me->def->original_id, vm_ci_mid(ci), me->owner, val, 0); } } while (0);
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, me->owner, me->def->original_id, &args)) { do {} while (0); } } } while (0);
return val;
}
static VALUE
vm_call_cfunc(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
const struct rb_callinfo *ci = calling->ci;
((void)0);
CALLER_SETUP_ARG(reg_cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(reg_cfp, calling, ci);
CC_SET_FASTPATH(calling->cc, vm_call_cfunc_with_frame, !rb_splat_or_kwargs_p(ci) && !calling->kw_splat);
return vm_call_cfunc_with_frame(ec, reg_cfp, calling);
}
static VALUE
vm_call_ivar(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
const struct rb_callcache *cc = calling->cc;
((void)0);
cfp->sp -= 1;
VALUE ivar = vm_getivar(calling->recv, vm_cc_cme(cc)->def->body.attr.id, ((void *)0), ((void *)0), cc, 1);
return ivar;
}
static VALUE
vm_call_attrset_direct(rb_execution_context_t *ec, rb_control_frame_t *cfp, const struct rb_callcache *cc, VALUE obj)
{
((void)0);
VALUE val = *(cfp->sp - 1);
cfp->sp -= 2;
attr_index_t index = vm_cc_attr_index(cc);
shape_id_t dest_shape_id = vm_cc_attr_index_dest_shape_id(cc);
ID id = vm_cc_cme(cc)->def->body.attr.id;
do { VALUE frozen_obj = (obj); if ((__builtin_expect(!!(RB_OBJ_FROZEN(frozen_obj)), 0))) { rb_error_frozen_object(frozen_obj); } } while (0);
VALUE res = vm_setivar(obj, id, val, dest_shape_id, index);
if (RB_UNDEF_P(res)) {
switch (RB_BUILTIN_TYPE(obj)) {
case RUBY_T_OBJECT:
case RUBY_T_CLASS:
case RUBY_T_MODULE:
break;
default:
{
res = vm_setivar_default(obj, id, val, dest_shape_id, index);
if (!RB_UNDEF_P(res)) {
return res;
}
}
}
res = vm_setivar_slowpath_attr(obj, id, val, cc);
}
return res;
}
static VALUE
vm_call_attrset(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
return vm_call_attrset_direct(ec, cfp, calling->cc, calling->recv);
}static inline
_Bool
rb_vm_call_ivar_attrset_p(const vm_call_handler ch)
{
return (ch == vm_call_ivar || ch == vm_call_attrset);
}
static inline VALUE
vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv)
{
rb_proc_t *proc;
VALUE val;
const struct rb_callcache *cc = calling->cc;
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
VALUE procv = cme->def->body.bmethod.proc;
if (!RB_FL_TEST_RAW((procv), RUBY_FL_SHAREABLE) &&
cme->def->body.bmethod.defined_ractor != rb_ractor_self(rb_ec_ractor_ptr(ec))) {
rb_raise(rb_eRuntimeError, "defined with an un-shareable Proc in a different Ractor");
}
(((proc)) = (rb_proc_t*)((struct RData *)(((procv))))->data);
val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->kw_splat, calling->block_handler, vm_cc_cme(cc));
return val;
}
static VALUE
vm_call_bmethod(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
VALUE *argv;
int argc;
const struct rb_callinfo *ci = calling->ci;
CALLER_SETUP_ARG(cfp, calling, ci);
argc = calling->argc;
argv = ((VALUE *)__builtin_alloca (rbimpl_size_mul_or_raise(sizeof(VALUE), (argc))));
ruby_nonempty_memcpy((argv), (cfp->sp - argc), rbimpl_size_mul_or_raise(sizeof(VALUE), (argc)));
cfp->sp += - argc - 1;
return vm_call_bmethod_body(ec, calling, argv);
}static inline
__attribute__ ((__visibility__("default"))) VALUE
rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner)
{
VALUE klass = current_class;
if (RB_TYPE_P(klass, RUBY_T_ICLASS) && RB_FL_TEST(klass, ((VALUE)RUBY_FL_USER0)) &&
RB_TYPE_P(RBASIC_CLASS(klass), RUBY_T_CLASS)) {
klass = RBASIC_CLASS(klass);
}
while (RB_TEST(klass)) {
VALUE owner = RB_TYPE_P(klass, RUBY_T_ICLASS) ? RBASIC_CLASS(klass) : klass;
if (owner == target_owner) {
return klass;
}
klass = RCLASS_SUPER(klass);
}
return current_class;
}
static const rb_callable_method_entry_t *
aliased_callable_method_entry(const rb_callable_method_entry_t *me)
{
const rb_method_entry_t *orig_me = me->def->body.alias.original_me;
const rb_callable_method_entry_t *cme;
if (orig_me->defined_class == 0) {
VALUE defined_class = rb_find_defined_class_by_owner(me->defined_class, orig_me->owner);
((void)0);
cme = rb_method_entry_complement_defined_class(orig_me, me->called_id, defined_class);
if (me->def->reference_count == 1) {
rb_obj_write((VALUE)(me), ((VALUE *)(&me->def->body.alias.original_me)), (VALUE)(cme), "./vm_insnhelper.c", 3429);
}
else {
rb_method_definition_t *def =
rb_method_definition_create(VM_METHOD_TYPE_ALIAS, me->def->original_id);
rb_method_definition_set((rb_method_entry_t *)me, def, (void *)cme);
}
}
else {
cme = (const rb_callable_method_entry_t *)orig_me;
}
((void)0);
return cme;
}static inline
const rb_callable_method_entry_t *
rb_aliased_callable_method_entry(const rb_callable_method_entry_t *me)
{
return aliased_callable_method_entry(me);
}
static VALUE
vm_call_alias(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
calling->cc = &(struct rb_callcache) { .flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE) | ((VALUE)RUBY_FL_EXIVAR), .klass = ((VALUE)RUBY_Qundef), .cme_ = aliased_callable_method_entry(vm_cc_cme(calling->cc)), .call_ = vm_call_general, .aux_ = {{0}}, };
return vm_call_method_each_type(ec, cfp, calling);
}
static enum method_missing_reason
ci_missing_reason(const struct rb_callinfo *ci)
{
enum method_missing_reason stat = MISSING_NOENTRY;
if (vm_ci_flag(ci) & (0x01 << VM_CALL_VCALL_bit)) stat |= MISSING_VCALL;
if (vm_ci_flag(ci) & (0x01 << VM_CALL_FCALL_bit)) stat |= MISSING_FCALL;
if (vm_ci_flag(ci) & (0x01 << VM_CALL_SUPER_bit)) stat |= MISSING_SUPER;
return stat;
}
static VALUE vm_call_method_missing(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling);
static VALUE
vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE symbol, int flags)
{
((__builtin_expect(!!(!!(calling->argc >= 0)), 1)) ? ((void)0) : __builtin_unreachable());
enum method_missing_reason missing_reason = MISSING_NOENTRY;
int argc = calling->argc;
VALUE recv = calling->recv;
VALUE klass = rb_class_of(recv);
ID mid = rb_check_id(&symbol);
flags |= (0x01 << VM_CALL_OPT_SEND_bit) | (calling->kw_splat ? (0x01 << VM_CALL_KW_SPLAT_bit) : 0);
if ((__builtin_expect(!!(! mid), 0))) {
mid = idMethodMissing;
missing_reason = ci_missing_reason(ci);
ec->method_missing_reason = missing_reason;
int i = argc;
do { __extension__ _Static_assert(sizeof(*((reg_cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((reg_cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((reg_cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((reg_cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((reg_cfp)->sp)[((1))]; if ((__builtin_expect(!!(((reg_cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
(((reg_cfp)->sp) += (((1))));
memmove((&(*(((((reg_cfp)->sp)))-(i - 1)-1))), (&(*(((((reg_cfp)->sp)))-(i)-1))), rbimpl_size_mul_or_raise(sizeof(VALUE), (i)));
argc = ++calling->argc;
if (rb_method_basic_definition_p(klass, idMethodMissing)) {
(*(((((reg_cfp)->sp)))-(i)-1)) = symbol;
int priv = vm_ci_flag(ci) & ((0x01 << VM_CALL_FCALL_bit) | (0x01 << VM_CALL_VCALL_bit));
const VALUE *argv = (((((reg_cfp)->sp)))-(argc));
VALUE exc = rb_make_no_method_exception(
rb_eNoMethodError, 0, recv, argc, argv, priv);
rb_exc_raise(exc);
}
else {
(*(((((reg_cfp)->sp)))-(i)-1)) = rb_str_intern(symbol);
}
}
calling->ci = &(struct rb_callinfo) { .flags = RUBY_T_IMEMO | (imemo_callinfo << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_USER4), .mid = mid, .flag = flags, .argc = argc, .kwarg = vm_ci_kwarg(ci), };
calling->cc = &(struct rb_callcache) { .flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE) | ((VALUE)RUBY_FL_EXIVAR), .klass = klass, .cme_ = rb_callable_method_entry_with_refinements(klass, mid, ((void *)0)), .call_ = vm_call_general, .aux_ = { .method_missing_reason = missing_reason }, };
if (flags & (0x01 << VM_CALL_FCALL_bit)) {
return vm_call_method(ec, reg_cfp, calling);
}
const struct rb_callcache *cc = calling->cc;
((void)0);
if (vm_cc_cme(cc) != ((void *)0)) {
switch ((rb_method_visibility_t)(((vm_cc_cme(cc))->flags & (((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+0))) {
case METHOD_VISI_PUBLIC:
return vm_call_method_each_type(ec, reg_cfp, calling);
case METHOD_VISI_PRIVATE:
vm_cc_method_missing_reason_set(cc, MISSING_PRIVATE);
break;
case METHOD_VISI_PROTECTED:
vm_cc_method_missing_reason_set(cc, MISSING_PROTECTED);
break;
default:
__builtin_unreachable();
}
return vm_call_method_missing(ec, reg_cfp, calling);
}
return vm_call_method_nome(ec, reg_cfp, calling);
}
static VALUE
vm_call_opt_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
int i;
VALUE sym;
CALLER_SETUP_ARG(reg_cfp, calling, calling->ci);
i = calling->argc - 1;
if (calling->argc == 0) {
rb_raise(rb_eArgError, "no method name given");
}
else {
sym = (*(((((reg_cfp)->sp)))-(i)-1));
if (i > 0) {
memmove((&(*(((((reg_cfp)->sp)))-(i)-1))), (&(*(((((reg_cfp)->sp)))-(i-1)-1))), rbimpl_size_mul_or_raise(sizeof(VALUE), (i)));
}
calling->argc -= 1;
(((reg_cfp)->sp) -= (((1))));
return vm_call_symbol(ec, reg_cfp, calling, calling->ci, sym, (0x01 << VM_CALL_FCALL_bit));
}
}
static VALUE
vm_call_method_missing_body(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling,
const struct rb_callinfo *orig_ci, enum method_missing_reason reason)
{
((void)0);
VALUE *argv = (((((reg_cfp)->sp)))-(calling->argc));
unsigned int argc;
CALLER_SETUP_ARG(reg_cfp, calling, orig_ci);
argc = calling->argc + 1;
unsigned int flag = (0x01 << VM_CALL_FCALL_bit) | (0x01 << VM_CALL_OPT_SEND_bit) | (calling->kw_splat ? (0x01 << VM_CALL_KW_SPLAT_bit) : 0);
calling->argc = argc;
do { __extension__ _Static_assert(sizeof(*((reg_cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((reg_cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((reg_cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((reg_cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((reg_cfp)->sp)[((1))]; if ((__builtin_expect(!!(((reg_cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
;
if (argc > 1) {
memmove((argv+1), (argv), rbimpl_size_mul_or_raise(sizeof(VALUE), (argc-1)));
}
argv[0] = rb_id2sym(vm_ci_mid(orig_ci));
(((reg_cfp)->sp) += (((1))));
ec->method_missing_reason = reason;
calling->ci = &(struct rb_callinfo) { .flags = RUBY_T_IMEMO | (imemo_callinfo << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_USER4), .mid = idMethodMissing, .flag = flag, .argc = argc, .kwarg = vm_ci_kwarg(orig_ci), };
calling->cc = &(struct rb_callcache) { .flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE) | ((VALUE)RUBY_FL_EXIVAR), .klass = ((VALUE)RUBY_Qundef), .cme_ = rb_callable_method_entry_without_refinements(rb_class_of(calling->recv), idMethodMissing, ((void *)0)), .call_ = vm_call_general, .aux_ = {{ 0 }}, };
return vm_call_method(ec, reg_cfp, calling);
}
static VALUE
vm_call_method_missing(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
return vm_call_method_missing_body(ec, reg_cfp, calling, calling->ci, vm_cc_cmethod_missing_reason(calling->cc));
}
static const rb_callable_method_entry_t *refined_method_callable_without_refinement(const rb_callable_method_entry_t *me);
static VALUE
vm_call_zsuper(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, VALUE klass)
{
klass = RCLASS_SUPER(klass);
const rb_callable_method_entry_t *cme = klass ? rb_callable_method_entry(klass, vm_ci_mid(calling->ci)) : ((void *)0);
if (cme == ((void *)0)) {
return vm_call_method_nome(ec, cfp, calling);
}
if (cme->def->type == VM_METHOD_TYPE_REFINED &&
cme->def->body.refined.orig_me) {
cme = refined_method_callable_without_refinement(cme);
}
calling->cc = &(struct rb_callcache) { .flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE) | ((VALUE)RUBY_FL_EXIVAR), .klass = ((VALUE)RUBY_Qundef), .cme_ = cme, .call_ = vm_call_general, .aux_ = {{ 0 }}, };
return vm_call_method_each_type(ec, cfp, calling);
}
static inline VALUE
find_refinement(VALUE refinements, VALUE klass)
{
if (RB_NIL_P(refinements)) {
return ((VALUE)RUBY_Qnil);
}
return rb_hash_lookup(refinements, klass);
}
__attribute__((__pure__)) static rb_control_frame_t * current_method_entry(const rb_execution_context_t *ec, rb_control_frame_t *cfp);
static rb_control_frame_t *
current_method_entry(const rb_execution_context_t *ec, rb_control_frame_t *cfp)
{
rb_control_frame_t *top_cfp = cfp;
if (cfp->iseq && ((cfp->iseq)->body)->type == ISEQ_TYPE_BLOCK) {
const rb_iseq_t *local_iseq = ((cfp->iseq)->body)->local_iseq;
do {
cfp = ((cfp)+1);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)) {
return top_cfp;
}
} while (cfp->iseq != local_iseq);
}
return cfp;
}
static const rb_callable_method_entry_t *
refined_method_callable_without_refinement(const rb_callable_method_entry_t *me)
{
const rb_method_entry_t *orig_me = me->def->body.refined.orig_me;
const rb_callable_method_entry_t *cme;
if (orig_me->defined_class == 0) {
cme = ((void *)0);
rb_notimplement();
}
else {
cme = (const rb_callable_method_entry_t *)orig_me;
}
((void)0);
if ((!(cme) || !(cme)->def || (cme)->def->type == VM_METHOD_TYPE_UNDEF)) {
cme = ((void *)0);
}
return cme;
}
static const rb_callable_method_entry_t *
search_refined_method(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
ID mid = vm_ci_mid(calling->ci);
const rb_cref_t *cref = vm_get_cref(cfp->ep);
const struct rb_callcache * const cc = calling->cc;
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
for (; cref; cref = CREF_NEXT(cref)) {
const VALUE refinement = find_refinement(CREF_REFINEMENTS(cref), vm_cc_cme(cc)->owner);
if (RB_NIL_P(refinement)) continue;
const rb_callable_method_entry_t *const ref_me =
rb_callable_method_entry(refinement, mid);
if (ref_me) {
if (vm_cc_call(cc) == vm_call_super_method) {
const rb_control_frame_t *top_cfp = current_method_entry(ec, cfp);
const rb_callable_method_entry_t *top_me = rb_vm_frame_method_entry(top_cfp);
if (top_me && rb_method_definition_eq(ref_me->def, top_me->def)) {
continue;
}
}
if (cme->def->type != VM_METHOD_TYPE_REFINED ||
cme->def != ref_me->def) {
cme = ref_me;
}
if (ref_me->def->type != VM_METHOD_TYPE_REFINED) {
return cme;
}
}
else {
return ((void *)0);
}
}
if (vm_cc_cme(cc)->def->body.refined.orig_me) {
return refined_method_callable_without_refinement(vm_cc_cme(cc));
}
else {
VALUE klass = RCLASS_SUPER(vm_cc_cme(cc)->defined_class);
const rb_callable_method_entry_t *cme = klass ? rb_callable_method_entry(klass, mid) : ((void *)0);
return cme;
}
}
static VALUE
vm_call_refined(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
struct rb_callcache *ref_cc = &(struct rb_callcache) { .flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE) | ((VALUE)RUBY_FL_EXIVAR), .klass = ((VALUE)RUBY_Qundef), .cme_ = search_refined_method(ec, cfp, calling), .call_ = vm_call_general, .aux_ = {{ 0 }}, };
if (vm_cc_cme(ref_cc)) {
calling->cc= ref_cc;
return vm_call_method(ec, cfp, calling);
}
else {
return vm_call_method_nome(ec, cfp, calling);
}
}
static inline VALUE vm_invoke_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci, _Bool is_lambda, VALUE block_handler);
__attribute__((__noinline__)) static VALUE vm_invoke_block_opt_call(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE block_handler);
static VALUE
vm_invoke_block_opt_call(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE block_handler)
{
int argc = calling->argc;
if (argc > 0) memmove((&(*(((((reg_cfp)->sp)))-(argc)-1))), (&(*(((((reg_cfp)->sp)))-(argc-1)-1))), rbimpl_size_mul_or_raise(sizeof(VALUE), (argc)));
(((reg_cfp)->sp) -= (((1))));
return vm_invoke_block(ec, reg_cfp, calling, ci, 0, block_handler);
}
static VALUE
vm_call_opt_call(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
const struct rb_callinfo *ci = calling->ci;
VALUE procval = calling->recv;
return vm_invoke_block_opt_call(ec, reg_cfp, calling, ci, VM_BH_FROM_PROC(procval));
}
static VALUE
vm_call_opt_block_call(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
VALUE block_handler = VM_ENV_BLOCK_HANDLER(VM_CF_LEP(reg_cfp));
const struct rb_callinfo *ci = calling->ci;
if (((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CALL)]&((1 << 12))) == 0), 1)))) {
return vm_invoke_block_opt_call(ec, reg_cfp, calling, ci, block_handler);
}
else {
calling->recv = rb_vm_bh_to_procval(ec, block_handler);
calling->cc = rb_vm_search_method_slowpath(ci, rb_class_of(calling->recv));
return vm_call_general(ec, reg_cfp, calling);
}
}
static VALUE
vm_call_opt_struct_aref0(rb_execution_context_t *ec, struct rb_calling_info *calling)
{
VALUE recv = calling->recv;
((void)0);
((void)0);
((void)0);
const unsigned int off = vm_cc_cme(calling->cc)->def->body.optimized.index;
return internal_RSTRUCT_GET(recv, off);
}
static VALUE
vm_call_opt_struct_aref(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
VALUE ret = vm_call_opt_struct_aref0(ec, calling);
reg_cfp->sp -= 1;
return ret;
}
static VALUE
vm_call_opt_struct_aset0(rb_execution_context_t *ec, struct rb_calling_info *calling, VALUE val)
{
VALUE recv = calling->recv;
((void)0);
((void)0);
((void)0);
rb_check_frozen_inline(recv);
const unsigned int off = vm_cc_cme(calling->cc)->def->body.optimized.index;
internal_RSTRUCT_SET(recv, off, val);
return val;
}
static VALUE
vm_call_opt_struct_aset(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
VALUE ret = vm_call_opt_struct_aset0(ec, calling, *(reg_cfp->sp - 1));
reg_cfp->sp -= 2;
return ret;
}
__attribute__((__noinline__)) static VALUE vm_call_optimized(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_callinfo *ci, const struct rb_callcache *cc);
static VALUE
vm_call_optimized(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling,
const struct rb_callinfo *ci, const struct rb_callcache *cc)
{
switch (vm_cc_cme(cc)->def->body.optimized.type) {
case OPTIMIZED_METHOD_TYPE_SEND:
CC_SET_FASTPATH(cc, vm_call_opt_send, 1);
return vm_call_opt_send(ec, cfp, calling);
case OPTIMIZED_METHOD_TYPE_CALL:
CC_SET_FASTPATH(cc, vm_call_opt_call, 1);
return vm_call_opt_call(ec, cfp, calling);
case OPTIMIZED_METHOD_TYPE_BLOCK_CALL:
CC_SET_FASTPATH(cc, vm_call_opt_block_call, 1);
return vm_call_opt_block_call(ec, cfp, calling);
case OPTIMIZED_METHOD_TYPE_STRUCT_AREF:
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
rb_check_arity(calling->argc, 0, 0);
CC_SET_FASTPATH(cc, vm_call_opt_struct_aref, (vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SIMPLE_bit)));
return vm_call_opt_struct_aref(ec, cfp, calling);
case OPTIMIZED_METHOD_TYPE_STRUCT_ASET:
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
rb_check_arity(calling->argc, 1, 1);
CC_SET_FASTPATH(cc, vm_call_opt_struct_aset, (vm_ci_flag(ci) & (0x01 << VM_CALL_ARGS_SIMPLE_bit)));
return vm_call_opt_struct_aset(ec, cfp, calling);
default:
rb_bug("vm_call_method: unsupported optimized method type (%d)", vm_cc_cme(cc)->def->body.optimized.type);
}
}
COLDFUNC static VALUE
vm_call_method_each_type(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling) {
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
VALUE v;
switch (cme->def->type) {
case VM_METHOD_TYPE_ISEQ:
CC_SET_FASTPATH(cc, vm_call_iseq_setup, 1);
return vm_call_iseq_setup(ec, cfp, calling);
case VM_METHOD_TYPE_NOTIMPLEMENTED:
case VM_METHOD_TYPE_CFUNC:
CC_SET_FASTPATH(cc, vm_call_cfunc, 1);
return vm_call_cfunc(ec, cfp, calling);
case VM_METHOD_TYPE_ATTRSET:
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
rb_check_arity(calling->argc, 1, 1);
const unsigned int aset_mask = ((0x01 << VM_CALL_ARGS_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_bit) | (0x01 << VM_CALL_KWARG_bit));
if (vm_cc_markable(cc)) {
vm_cc_attr_index_initialize(cc, (((uintptr_t)1 << 32) - 1));
if ((__builtin_expect(!!(ruby_vm_event_flags & (0x0020 | 0x0040)), 0))) { do { const rb_event_flag_t flag_arg_ = (0x0020); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, ((VALUE)RUBY_Qundef), 0); } } while (0); v = vm_call_attrset_direct(ec, cfp, cc, calling->recv); do { const rb_event_flag_t flag_arg_ = (0x0040); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, (v), 0); } } while (0); } else { CC_SET_FASTPATH(cc, vm_call_attrset, !(vm_ci_flag(ci) & aset_mask)); v = vm_call_attrset_direct(ec, cfp, cc, calling->recv); };
}
else {
cc = &((struct rb_callcache) {
.flags = RUBY_T_IMEMO |
(imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) |
((VALUE)RUBY_FL_FREEZE) |
((VALUE)(((uintptr_t)1 << 32) - 1) << ((8 * 8) - 32)) |
((VALUE)RUBY_FL_EXIVAR),
.klass = cc->klass,
.cme_ = cc->cme_,
.call_ = cc->call_,
.aux_ = {
.attr = {
.value = (((uintptr_t)1 << 32) - 1) << ((8 * 8) - 32),
}
},
});
if ((__builtin_expect(!!(ruby_vm_event_flags & (0x0020 | 0x0040)), 0))) { do { const rb_event_flag_t flag_arg_ = (0x0020); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, ((VALUE)RUBY_Qundef), 0); } } while (0); v = vm_call_attrset_direct(ec, cfp, cc, calling->recv); do { const rb_event_flag_t flag_arg_ = (0x0040); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, (v), 0); } } while (0); } else { CC_SET_FASTPATH(cc, vm_call_attrset, !(vm_ci_flag(ci) & aset_mask)); v = vm_call_attrset_direct(ec, cfp, cc, calling->recv); };
}
return v;
case VM_METHOD_TYPE_IVAR:
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
rb_check_arity(calling->argc, 0, 0);
vm_cc_attr_index_initialize(cc, (((uintptr_t)1 << 32) - 1));
const unsigned int ivar_mask = ((0x01 << VM_CALL_ARGS_SPLAT_bit) | (0x01 << VM_CALL_KW_SPLAT_bit));
if ((__builtin_expect(!!(ruby_vm_event_flags & (0x0020 | 0x0040)), 0))) { do { const rb_event_flag_t flag_arg_ = (0x0020); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, ((VALUE)RUBY_Qundef), 0); } } while (0); v = vm_call_ivar(ec, cfp, calling); do { const rb_event_flag_t flag_arg_ = (0x0040); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, (v), 0); } } while (0); } else { CC_SET_FASTPATH(cc, vm_call_ivar, !(vm_ci_flag(ci) & ivar_mask)); v = vm_call_ivar(ec, cfp, calling); };
return v;
case VM_METHOD_TYPE_MISSING:
vm_cc_method_missing_reason_set(cc, 0);
CC_SET_FASTPATH(cc, vm_call_method_missing, 1);
return vm_call_method_missing(ec, cfp, calling);
case VM_METHOD_TYPE_BMETHOD:
CC_SET_FASTPATH(cc, vm_call_bmethod, 1);
return vm_call_bmethod(ec, cfp, calling);
case VM_METHOD_TYPE_ALIAS:
CC_SET_FASTPATH(cc, vm_call_alias, 1);
return vm_call_alias(ec, cfp, calling);
case VM_METHOD_TYPE_OPTIMIZED:
return vm_call_optimized(ec, cfp, calling, ci, cc);
case VM_METHOD_TYPE_UNDEF:
break;
case VM_METHOD_TYPE_ZSUPER:
return vm_call_zsuper(ec, cfp, calling, (((rb_classext_t *)((char *)(vm_cc_cme(cc)->defined_class) + sizeof(struct RClass)))->origin_));
case VM_METHOD_TYPE_REFINED:
return vm_call_refined(ec, cfp, calling);
}
rb_bug("vm_call_method: unsupported method type (%d)", vm_cc_cme(cc)->def->type);
}
__attribute__((__noreturn__)) static void vm_raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj, int call_status);
static VALUE
vm_call_method_nome(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
const struct rb_callinfo *ci = calling->ci;
const int stat = ci_missing_reason(ci);
if (vm_ci_mid(ci) == idMethodMissing) {
rb_control_frame_t *reg_cfp = cfp;
VALUE *argv = (((((reg_cfp)->sp)))-(calling->argc));
vm_raise_method_missing(ec, calling->argc, argv, calling->recv, stat);
}
else {
return vm_call_method_missing_body(ec, cfp, calling, ci, stat);
}
}
static VALUE
vm_defined_class_for_protected_call(const rb_callable_method_entry_t *me)
{
VALUE defined_class = me->defined_class;
VALUE refined_class = (((rb_classext_t *)((char *)(defined_class) + sizeof(struct RClass)))->refined_class);
return RB_NIL_P(refined_class) ? defined_class : refined_class;
}
static inline VALUE
vm_call_method(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
const struct rb_callinfo *ci = calling->ci;
const struct rb_callcache *cc = calling->cc;
((void)0);
if (vm_cc_cme(cc) != ((void *)0)) {
switch ((rb_method_visibility_t)(((vm_cc_cme(cc))->flags & (((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+0))) {
case METHOD_VISI_PUBLIC:
return vm_call_method_each_type(ec, cfp, calling);
case METHOD_VISI_PRIVATE:
if (!(vm_ci_flag(ci) & (0x01 << VM_CALL_FCALL_bit))) {
enum method_missing_reason stat = MISSING_PRIVATE;
if (vm_ci_flag(ci) & (0x01 << VM_CALL_VCALL_bit)) stat |= MISSING_VCALL;
vm_cc_method_missing_reason_set(cc, stat);
CC_SET_FASTPATH(cc, vm_call_method_missing, 1);
return vm_call_method_missing(ec, cfp, calling);
}
return vm_call_method_each_type(ec, cfp, calling);
case METHOD_VISI_PROTECTED:
if (!(vm_ci_flag(ci) & ((0x01 << VM_CALL_OPT_SEND_bit) | (0x01 << VM_CALL_FCALL_bit)))) {
VALUE defined_class = vm_defined_class_for_protected_call(vm_cc_cme(cc));
if (!rb_obj_is_kind_of(cfp->self, defined_class)) {
vm_cc_method_missing_reason_set(cc, MISSING_PROTECTED);
return vm_call_method_missing(ec, cfp, calling);
}
else {
((void)0);
struct rb_callcache cc_on_stack = *cc;
RB_FL_SET_RAW((VALUE)&cc_on_stack, ((VALUE)RUBY_FL_FREEZE));
calling->cc = &cc_on_stack;
return vm_call_method_each_type(ec, cfp, calling);
}
}
return vm_call_method_each_type(ec, cfp, calling);
default:
rb_bug("unreachable");
}
}
else {
return vm_call_method_nome(ec, cfp, calling);
}
}
static VALUE
vm_call_general(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_method(ec, reg_cfp, calling);
}static inline
void
rb_vm_cc_general(const struct rb_callcache *cc)
{
((void)0);
((void)0);
*(vm_call_handler *)&cc->call_ = vm_call_general;
}
static VALUE
vm_call_super_method(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling)
{
((void)0);
if (ec == ((void *)0)) rb_bug("unreachable");
((void)0);
return vm_call_method(ec, reg_cfp, calling);
}
static inline VALUE
vm_search_normal_superclass(VALUE klass)
{
if (RB_BUILTIN_TYPE(klass) == RUBY_T_ICLASS &&
RB_TYPE_P(((struct RBasic *)(klass))->klass, RUBY_T_MODULE) &&
RB_FL_TEST_RAW(((struct RBasic *)(klass))->klass, RMODULE_IS_REFINEMENT)) {
klass = ((struct RBasic *)(klass))->klass;
}
klass = (((rb_classext_t *)((char *)(klass) + sizeof(struct RClass)))->origin_);
return RCLASS_SUPER(klass);
}
__attribute__((__noreturn__)) static void vm_super_outside(void);
static void
vm_super_outside(void)
{
rb_raise(rb_eNoMethodError, "super called outside of method");
}
static const struct rb_callcache *
empty_cc_for_super(void)
{
return rb_vm_empty_cc_for_super();
}
static const struct rb_callcache *
vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *cd, VALUE recv)
{
VALUE current_defined_class;
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(reg_cfp);
if (!me) {
vm_super_outside();
}
current_defined_class = vm_defined_class_for_protected_call(me);
if (RB_BUILTIN_TYPE(current_defined_class) != RUBY_T_MODULE &&
reg_cfp->iseq != method_entry_iseqptr(me) &&
!rb_obj_is_kind_of(recv, current_defined_class)) {
VALUE m = RB_TYPE_P(current_defined_class, RUBY_T_ICLASS) ?
(((rb_classext_t *)((char *)(current_defined_class) + sizeof(struct RClass)))->includer) : current_defined_class;
if (m) {
rb_raise(rb_eTypeError,
"self has wrong type to call super in this context: "
"%""l""i" "\v"" (expected %""l""i" "\v"")",
rb_obj_class(recv), m);
}
}
if (me->def->type == VM_METHOD_TYPE_BMETHOD && (vm_ci_flag(cd->ci) & (0x01 << VM_CALL_ZSUPER_bit))) {
rb_raise(rb_eRuntimeError,
"implicit argument passing of super from method defined"
" by define_method() is not supported."
" Specify all arguments explicitly.");
}
ID mid = me->def->original_id;
cd->ci = vm_ci_new_runtime_(mid, vm_ci_flag(cd->ci), vm_ci_argc(cd->ci), vm_ci_kwarg(cd->ci), "./vm_insnhelper.c", 4198);
(rb_obj_written((VALUE)(reg_cfp->iseq), (VALUE)(((VALUE)RUBY_Qundef)), (VALUE)(cd->ci), "./vm_insnhelper.c", 4200));
const struct rb_callcache *cc;
VALUE klass = vm_search_normal_superclass(me->defined_class);
if (!klass) {
cc = vm_cc_new(klass, ((void *)0), vm_call_method_missing);
rb_obj_write((VALUE)(reg_cfp->iseq), ((VALUE *)(&cd->cc)), (VALUE)(cc), "./vm_insnhelper.c", 4209);
}
else {
cc = vm_search_method_fastpath((VALUE)reg_cfp->iseq, cd, klass);
const rb_callable_method_entry_t *cached_cme = vm_cc_cme(cc);
if (cached_cme == ((void *)0)) {
cd->cc = empty_cc_for_super();
}
else if (cached_cme->called_id != mid) {
const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
if (cme) {
cc = vm_cc_new(klass, cme, vm_call_super_method);
rb_obj_write((VALUE)(reg_cfp->iseq), ((VALUE *)(&cd->cc)), (VALUE)(cc), "./vm_insnhelper.c", 4224);
}
else {
cd->cc = cc = empty_cc_for_super();
}
}
else {
switch (cached_cme->def->type) {
case VM_METHOD_TYPE_REFINED:
case VM_METHOD_TYPE_ATTRSET:
case VM_METHOD_TYPE_IVAR:
vm_cc_call_set(cc, vm_call_super_method);
break;
default:
break;
}
}
}
((void)0);
return cc;
}
static inline int
block_proc_is_lambda(const VALUE procval)
{
rb_proc_t *proc;
if (procval) {
(((proc)) = (rb_proc_t*)((struct RData *)(((procval))))->data);
return proc->is_lambda;
}
else {
return 0;
}
}
static VALUE
vm_yield_with_cfunc(rb_execution_context_t *ec,
const struct rb_captured_block *captured,
VALUE self, int argc, const VALUE *argv, int kw_splat, VALUE block_handler,
const rb_callable_method_entry_t *me)
{
int is_lambda = 0;
VALUE val, arg, blockarg;
int frame_flag;
const struct vm_ifunc *ifunc = captured->code.ifunc;
if (is_lambda) {
arg = rb_ary_new_from_values(argc, argv);
}
else if (argc == 0) {
arg = ((VALUE)RUBY_Qnil);
}
else {
arg = argv[0];
}
blockarg = rb_vm_bh_to_procval(ec, block_handler);
frame_flag = VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME | (me ? VM_FRAME_FLAG_BMETHOD : 0);
if (kw_splat) {
frame_flag |= VM_FRAME_FLAG_CFRAME_KW;
}
vm_push_frame(ec, (const rb_iseq_t *)captured->code.ifunc,
frame_flag,
self,
((VALUE)((captured->ep)) | (0x01)),
(VALUE)me,
0, ec->cfp->sp, 0, 0);
val = (*ifunc->func)(arg, (VALUE)ifunc->data, argc, argv, blockarg);
rb_vm_pop_frame(ec);
return val;
}
static VALUE
vm_yield_with_symbol(rb_execution_context_t *ec, VALUE symbol, int argc, const VALUE *argv, int kw_splat, VALUE block_handler)
{
return rb_sym_proc_call(rb_sym2id(symbol), argc, argv, kw_splat, rb_vm_bh_to_procval(ec, block_handler));
}
static inline int
vm_callee_setup_block_arg_arg0_splat(rb_control_frame_t *cfp, const rb_iseq_t *iseq, VALUE *argv, VALUE ary)
{
int i;
long len = rb_array_len(ary);
do { __extension__ _Static_assert(sizeof(*((cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((cfp)->sp)[((((iseq)->body)->param.lead_num))]; if ((__builtin_expect(!!(((cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
for (i=0; i<len && i<((iseq)->body)->param.lead_num; i++) {
argv[i] = RARRAY_AREF(ary, i);
}
return i;
}
static inline VALUE
vm_callee_setup_block_arg_arg0_check(VALUE *argv)
{
VALUE ary, arg0 = argv[0];
ary = rb_check_array_type(arg0);
((void)0);
return ary;
}
static int
vm_callee_setup_block_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, const struct rb_callinfo *ci, const rb_iseq_t *iseq, VALUE *argv, const enum arg_setup_type arg_setup_type)
{
if (rb_simple_iseq_p(iseq)) {
rb_control_frame_t *cfp = ec->cfp;
VALUE arg0;
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
if (arg_setup_type == arg_setup_block &&
calling->argc == 1 &&
((iseq)->body)->param.flags.has_lead &&
!((iseq)->body)->param.flags.ambiguous_param0 &&
!RB_NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) {
calling->argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
}
if (calling->argc != ((iseq)->body)->param.lead_num) {
if (arg_setup_type == arg_setup_block) {
if (calling->argc < ((iseq)->body)->param.lead_num) {
int i;
do { __extension__ _Static_assert(sizeof(*((cfp)->sp)) == sizeof(VALUE), "sizeof_sp" ": " "sizeof(*((cfp)->sp)) == sizeof(VALUE)"); __extension__ _Static_assert(sizeof(*((cfp))) == sizeof(rb_control_frame_t), "sizeof_cfp" ": " "sizeof(*((cfp))) == sizeof(rb_control_frame_t)"); const struct rb_control_frame_struct *bound = (void *)&((cfp)->sp)[((((iseq)->body)->param.lead_num))]; if ((__builtin_expect(!!(((cfp)) <= &bound[1]), 0))) { vm_stackoverflow(); } } while (0);
for (i=calling->argc; i<((iseq)->body)->param.lead_num; i++) argv[i] = ((VALUE)RUBY_Qnil);
calling->argc = ((iseq)->body)->param.lead_num;
}
else if (calling->argc > ((iseq)->body)->param.lead_num) {
calling->argc = ((iseq)->body)->param.lead_num;
}
}
else {
argument_arity_error(ec, iseq, calling->argc, ((iseq)->body)->param.lead_num, ((iseq)->body)->param.lead_num);
}
}
return 0;
}
else {
return setup_parameters_complex(ec, iseq, calling, ci, argv, arg_setup_type);
}
}
static int
vm_yield_setup_args(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int argc, VALUE *argv, int kw_splat, VALUE block_handler, enum arg_setup_type arg_setup_type)
{
struct rb_calling_info calling_entry, *calling;
calling = &calling_entry;
calling->argc = argc;
calling->block_handler = block_handler;
calling->kw_splat = kw_splat;
calling->recv = ((VALUE)RUBY_Qundef);
struct rb_callinfo dummy_ci = (struct rb_callinfo) { .flags = RUBY_T_IMEMO | (imemo_callinfo << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_USER4), .mid = 0, .flag = (kw_splat ? (0x01 << VM_CALL_KW_SPLAT_bit) : 0), .argc = 0, .kwarg = 0, };
return vm_callee_setup_block_arg(ec, calling, &dummy_ci, iseq, argv, arg_setup_type);
}
static VALUE
vm_invoke_iseq_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
_Bool is_lambda, VALUE block_handler)
{
const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
const int arg_size = ((iseq)->body)->param.size;
VALUE * const rsp = ((((reg_cfp)->sp))) - calling->argc;
int opt_pc = vm_callee_setup_block_arg(ec, calling, ci, iseq, rsp, is_lambda ? arg_setup_method : arg_setup_block);
(((reg_cfp)->sp) = (((rsp))));
vm_push_frame(ec, iseq,
VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0),
captured->self,
((VALUE)((captured->ep)) | (0x01)), 0,
((iseq)->body)->iseq_encoded + opt_pc,
rsp + arg_size,
((iseq)->body)->local_table_size - arg_size, ((iseq)->body)->stack_max);
return ((VALUE)RUBY_Qundef);
}
static VALUE
vm_invoke_symbol_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
__attribute__ ((__unused__)) _Bool is_lambda, VALUE block_handler)
{
if (calling->argc < 1) {
rb_raise(rb_eArgError, "no receiver given");
}
else {
VALUE symbol = VM_BH_TO_SYMBOL(block_handler);
CALLER_SETUP_ARG(reg_cfp, calling, ci);
calling->recv = (*(((((reg_cfp)->sp)))-(--calling->argc)-1));
return vm_call_symbol(ec, reg_cfp, calling, ci, symbol, 0);
}
}
static VALUE
vm_invoke_ifunc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
__attribute__ ((__unused__)) _Bool is_lambda, VALUE block_handler)
{
VALUE val;
int argc;
const struct rb_captured_block *captured = VM_BH_TO_IFUNC_BLOCK(block_handler);
CALLER_SETUP_ARG(ec->cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(ec->cfp, calling, ci);
argc = calling->argc;
val = vm_yield_with_cfunc(ec, captured, captured->self, argc, (((((reg_cfp)->sp)))-(argc)), calling->kw_splat, calling->block_handler, ((void *)0));
((((reg_cfp)->sp) -= (((argc)))));
return val;
}
static VALUE
vm_proc_to_block_handler(VALUE procval)
{
const struct rb_block *block = vm_proc_block(procval);
switch (vm_block_type(block)) {
case block_type_iseq:
return VM_BH_FROM_ISEQ_BLOCK(&block->as.captured);
case block_type_ifunc:
return VM_BH_FROM_IFUNC_BLOCK(&block->as.captured);
case block_type_symbol:
return VM_BH_FROM_SYMBOL(block->as.symbol);
case block_type_proc:
return VM_BH_FROM_PROC(block->as.proc);
}
__builtin_unreachable();
return ((VALUE)RUBY_Qundef);
}
static VALUE
vm_invoke_proc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
_Bool is_lambda, VALUE block_handler)
{
while (vm_block_handler_type(block_handler) == block_handler_type_proc) {
VALUE proc = VM_BH_TO_PROC(block_handler);
is_lambda = block_proc_is_lambda(proc);
block_handler = vm_proc_to_block_handler(proc);
}
return vm_invoke_block(ec, reg_cfp, calling, ci, is_lambda, block_handler);
}
static inline VALUE
vm_invoke_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
_Bool is_lambda, VALUE block_handler)
{
VALUE (*func)(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
struct rb_calling_info *calling, const struct rb_callinfo *ci,
_Bool is_lambda, VALUE block_handler);
switch (vm_block_handler_type(block_handler)) {
case block_handler_type_iseq: func = vm_invoke_iseq_block; break;
case block_handler_type_ifunc: func = vm_invoke_ifunc_block; break;
case block_handler_type_proc: func = vm_invoke_proc_block; break;
case block_handler_type_symbol: func = vm_invoke_symbol_block; break;
default: rb_bug("vm_invoke_block: unreachable");
}
return func(ec, reg_cfp, calling, ci, is_lambda, block_handler);
}
static VALUE
vm_make_proc_with_iseq(const rb_iseq_t *blockiseq)
{
const rb_execution_context_t *ec = rb_current_execution_context(1);
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
struct rb_captured_block *captured;
if (cfp == 0) {
rb_bug("vm_make_proc_with_iseq: unreachable");
}
captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
captured->code.iseq = blockiseq;
return rb_vm_make_proc(ec, captured, rb_cProc);
}
static VALUE
vm_once_exec(VALUE iseq)
{
VALUE proc = vm_make_proc_with_iseq((rb_iseq_t *)iseq);
return rb_proc_call_with_block(proc, 0, 0, ((VALUE)RUBY_Qnil));
}
static VALUE
vm_once_clear(VALUE data)
{
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)data;
is->once.running_thread = ((void *)0);
return ((VALUE)RUBY_Qnil);
}
static _Bool
check_respond_to_missing(VALUE obj, VALUE v)
{
VALUE args[2];
VALUE r;
args[0] = obj; args[1] = ((VALUE)RUBY_Qfalse);
r = rb_check_funcall(v, idRespond_to_missing, 2, args);
if (!RB_UNDEF_P(r) && RB_TEST(r)) {
return 1;
}
else {
return 0;
}
}
static _Bool
vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE v)
{
VALUE klass;
enum defined_type type = (enum defined_type)op_type;
switch (type) {
case DEFINED_IVAR:
return rb_ivar_defined((((((reg_cfp)))->self)), rb_sym2id(obj));
break;
case DEFINED_GVAR:
return rb_gvar_defined(rb_sym2id(obj));
break;
case DEFINED_CVAR: {
const rb_cref_t *cref = vm_get_cref(((((reg_cfp)->ep))));
klass = vm_get_cvar_base(cref, (((reg_cfp))), 0);
return rb_cvar_defined(klass, rb_sym2id(obj));
break;
}
case DEFINED_CONST:
case DEFINED_CONST_FROM: {
_Bool allow_nil = type == DEFINED_CONST;
klass = v;
return vm_get_ev_const(ec, klass, rb_sym2id(obj), allow_nil, 1);
break;
}
case DEFINED_FUNC:
klass = rb_class_of(v);
return rb_ec_obj_respond_to(ec, v, rb_sym2id(obj), 1);
break;
case DEFINED_METHOD:{
VALUE klass = rb_class_of(v);
const rb_method_entry_t *me = rb_method_entry_with_refinements(klass, rb_sym2id(obj), ((void *)0));
if (me) {
switch ((rb_method_visibility_t)(((me)->flags & (((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+0))) {
case METHOD_VISI_PRIVATE:
break;
case METHOD_VISI_PROTECTED:
if (!rb_obj_is_kind_of((((((reg_cfp)))->self)), rb_class_real(me->defined_class))) {
break;
}
case METHOD_VISI_PUBLIC:
return 1;
break;
default:
rb_bug("vm_defined: unreachable: %u", (unsigned int)(rb_method_visibility_t)(((me)->flags & (((VALUE)RUBY_FL_USER4) | ((VALUE)RUBY_FL_USER5))) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+0)));
}
}
else {
return check_respond_to_missing(obj, v);
}
break;
}
case DEFINED_YIELD:
if (((VM_EP_LEP(((((reg_cfp)->ep)))))[(-1)]) != 0) {
return 1;
}
break;
case DEFINED_ZSUPER:
{
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry((((reg_cfp))));
if (me) {
VALUE klass = vm_search_normal_superclass(me->defined_class);
ID id = me->def->original_id;
return rb_method_boundp(klass, id, 0);
}
}
break;
case DEFINED_REF:{
return vm_getspecial(ec, (VM_EP_LEP(((((reg_cfp)->ep))))), ((VALUE)RUBY_Qfalse), RB_FIX2INT(obj)) != ((VALUE)RUBY_Qnil);
break;
}
default:
rb_bug("unimplemented defined? type (VM)");
break;
}
return 0;
}static inline
_Bool
rb_vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE v)
{
return vm_defined(ec, reg_cfp, op_type, obj, v);
}
static const VALUE *
vm_get_ep(const VALUE *const reg_ep, rb_num_t lv)
{
rb_num_t i;
const VALUE *ep = reg_ep;
for (i = 0; i < lv; i++) {
ep = ((VALUE *)((ep)[(-1)] & ~0x03));
}
return ep;
}
static VALUE
vm_get_special_object(const VALUE *const reg_ep,
enum vm_special_object_type type)
{
switch (type) {
case VM_SPECIAL_OBJECT_VMCORE:
return rb_mRubyVMFrozenCore;
case VM_SPECIAL_OBJECT_CBASE:
return vm_get_cbase(reg_ep);
case VM_SPECIAL_OBJECT_CONST_BASE:
return vm_get_const_base(reg_ep);
default:
rb_bug("putspecialobject insn: unknown value_type %d", type);
}
}
static VALUE
vm_concat_array(VALUE ary1, VALUE ary2st)
{
const VALUE ary2 = ary2st;
VALUE tmp1 = rb_check_to_array(ary1);
VALUE tmp2 = rb_check_to_array(ary2);
if (RB_NIL_P(tmp1)) {
tmp1 = __extension__ ({ const VALUE args_to_new_ary[] = {ary1}; if (__builtin_constant_p(1)) { __extension__ _Static_assert(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))) == (1), "rb_ary_new_from_args" ": " "numberof(args_to_new_ary) == (1)"); } rb_ary_new_from_values(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))), args_to_new_ary); });
}
if (RB_NIL_P(tmp2)) {
tmp2 = __extension__ ({ const VALUE args_to_new_ary[] = {ary2}; if (__builtin_constant_p(1)) { __extension__ _Static_assert(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))) == (1), "rb_ary_new_from_args" ": " "numberof(args_to_new_ary) == (1)"); } rb_ary_new_from_values(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))), args_to_new_ary); });
}
if (tmp1 == ary1) {
tmp1 = rb_ary_dup(ary1);
}
return rb_ary_concat(tmp1, tmp2);
}static inline
VALUE
rb_vm_concat_array(VALUE ary1, VALUE ary2st)
{
return vm_concat_array(ary1, ary2st);
}
static VALUE
vm_splat_array(VALUE flag, VALUE ary)
{
VALUE tmp = rb_check_to_array(ary);
if (RB_NIL_P(tmp)) {
return __extension__ ({ const VALUE args_to_new_ary[] = {ary}; if (__builtin_constant_p(1)) { __extension__ _Static_assert(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))) == (1), "rb_ary_new_from_args" ": " "numberof(args_to_new_ary) == (1)"); } rb_ary_new_from_values(((int)(sizeof(args_to_new_ary) / sizeof((args_to_new_ary)[0]))), args_to_new_ary); });
}
else if (RB_TEST(flag)) {
return rb_ary_dup(tmp);
}
else {
return tmp;
}
}static inline
VALUE
rb_vm_splat_array(VALUE flag, VALUE ary)
{
return vm_splat_array(flag, ary);
}
static VALUE
vm_check_match(rb_execution_context_t *ec, VALUE target, VALUE pattern, rb_num_t flag)
{
enum vm_check_match_type type = ((int)flag) & 0x03;
if (flag & 0x04) {
long i;
const long n = rb_array_len(pattern);
for (i = 0; i < n; i++) {
VALUE v = RARRAY_AREF(pattern, i);
VALUE c = check_match(ec, v, target, type);
if (RB_TEST(c)) {
return c;
}
}
return ((VALUE)RUBY_Qfalse);
}
else {
return check_match(ec, pattern, target, type);
}
}
static VALUE
vm_check_keyword(lindex_t bits, lindex_t idx, const VALUE *ep)
{
const VALUE kw_bits = *(ep - bits);
if (RB_FIXNUM_P(kw_bits)) {
unsigned int b = (unsigned int)rb_fix2ulong(kw_bits);
if ((idx < (32-1)) && (b & (0x01 << idx)))
return ((VALUE)RUBY_Qfalse);
}
else {
((void)0);
if (rb_hash_has_key(kw_bits, __builtin_choose_expr( __builtin_constant_p(idx), ((VALUE)(idx)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(idx)))) return ((VALUE)RUBY_Qfalse);
}
return ((VALUE)RUBY_Qtrue);
}
static void
vm_dtrace(rb_event_flag_t flag, rb_execution_context_t *ec)
{
if (0 ||
0 ||
0 ||
0) {
switch (flag) {
case 0x0008:
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, 0, 0, &args)) { do {} while (0); } } } while (0);
return;
case 0x0020:
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, 0, 0, &args)) { do {} while (0); } } } while (0);
return;
case 0x0010:
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, 0, 0, &args)) { do {} while (0); } } } while (0);
return;
case 0x0040:
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, 0, 0, &args)) { do {} while (0); } } } while (0);
return;
}
}
}
static VALUE
vm_const_get_under(ID id, rb_num_t flags, VALUE cbase)
{
if (!rb_const_defined_at(cbase, id)) {
return 0;
}
else if (((flags) & 0x08)) {
return rb_public_const_get_at(cbase, id);
}
else {
return rb_const_get_at(cbase, id);
}
}
static VALUE
vm_check_if_class(ID id, rb_num_t flags, VALUE super, VALUE klass)
{
if (!RB_TYPE_P(klass, RUBY_T_CLASS)) {
return 0;
}
else if (((flags) & 0x10)) {
VALUE tmp = rb_class_real(RCLASS_SUPER(klass));
if (tmp != super) {
rb_raise(rb_eTypeError,
"superclass mismatch for class %""l""i" "\v""",
rb_id2str(id));
}
else {
return klass;
}
}
else {
return klass;
}
}
static VALUE
vm_check_if_module(ID id, VALUE mod)
{
if (!RB_TYPE_P(mod, RUBY_T_MODULE)) {
return 0;
}
else {
return mod;
}
}
static VALUE
declare_under(ID id, VALUE cbase, VALUE c)
{
rb_set_class_path_string(c, cbase, rb_id2str(id));
rb_const_set(cbase, id, c);
return c;
}
static VALUE
vm_declare_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
{
VALUE s = ((flags) & 0x10) ? super : rb_cObject;
VALUE c = declare_under(id, cbase, rb_define_class_id(id, s));
rb_define_alloc_func(c, rb_get_alloc_func(c));
rb_class_inherited(s, c);
return c;
}
static VALUE
vm_declare_module(ID id, VALUE cbase)
{
return declare_under(id, cbase, rb_module_new());
}
__attribute__((__noreturn__)) static void unmatched_redefinition(const char *type, VALUE cbase, ID id, VALUE old);
static void
unmatched_redefinition(const char *type, VALUE cbase, ID id, VALUE old)
{
VALUE name = rb_id2str(id);
VALUE message = rb_sprintf("%""l""i" "\v"" is not a %s",
name, type);
VALUE location = rb_const_source_location_at(cbase, id);
if (!RB_NIL_P(location)) {
rb_str_catf(message, "\n%""l""i" "\v"":%""l""i" "\v"":"
" previous definition of %""l""i" "\v"" was here",
rb_ary_entry(location, 0), rb_ary_entry(location, 1), name);
}
rb_exc_raise(rb_exc_new_str(rb_eTypeError, message));
}
static VALUE
vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
{
VALUE klass;
if (((flags) & 0x10) && !RB_TYPE_P(super, RUBY_T_CLASS)) {
rb_raise(rb_eTypeError,
"superclass must be an instance of Class (given an instance of %""l""i" "\v"")",
rb_obj_class(super));
}
vm_check_if_namespace(cbase);
rb_autoload_load(cbase, id);
if ((klass = vm_const_get_under(id, flags, cbase)) != 0) {
if (!vm_check_if_class(id, flags, super, klass))
unmatched_redefinition("class", cbase, id, klass);
return klass;
}
else {
return vm_declare_class(id, flags, cbase, super);
}
}
static VALUE
vm_define_module(ID id, rb_num_t flags, VALUE cbase)
{
VALUE mod;
vm_check_if_namespace(cbase);
if ((mod = vm_const_get_under(id, flags, cbase)) != 0) {
if (!vm_check_if_module(id, mod))
unmatched_redefinition("module", cbase, id, mod);
return mod;
}
else {
return vm_declare_module(id, cbase);
}
}
static VALUE
vm_find_or_create_class_by_id(ID id,
rb_num_t flags,
VALUE cbase,
VALUE super)
{
rb_vm_defineclass_type_t type = ((rb_vm_defineclass_type_t)(flags) & VM_DEFINECLASS_TYPE_MASK);
switch (type) {
case VM_DEFINECLASS_TYPE_CLASS:
return vm_define_class(id, flags, cbase, super);
case VM_DEFINECLASS_TYPE_SINGLETON_CLASS:
return rb_singleton_class(cbase);
case VM_DEFINECLASS_TYPE_MODULE:
return vm_define_module(id, flags, cbase);
default:
rb_bug("unknown defineclass type: %d", (int)type);
}
}
static rb_method_visibility_t
vm_scope_visibility_get(const rb_execution_context_t *ec)
{
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
if (!vm_env_cref_by_cref(cfp->ep)) {
return METHOD_VISI_PUBLIC;
}
else {
return CREF_SCOPE_VISI(vm_ec_cref(ec))->method_visi;
}
}
static int
vm_scope_module_func_check(const rb_execution_context_t *ec)
{
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
if (!vm_env_cref_by_cref(cfp->ep)) {
return 0;
}
else {
return CREF_SCOPE_VISI(vm_ec_cref(ec))->module_func;
}
}
static void
vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqval, int is_singleton)
{
VALUE klass;
rb_method_visibility_t visi;
rb_cref_t *cref = vm_ec_cref(ec);
if (is_singleton) {
klass = rb_singleton_class(obj);
visi = METHOD_VISI_PUBLIC;
}
else {
klass = CREF_CLASS_FOR_DEFINITION(cref);
visi = vm_scope_visibility_get(ec);
}
if (RB_NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to add method");
}
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
if (id == (__builtin_constant_p("initialize") ? __extension__ ({ static ID rbimpl_id; rbimpl_intern_const(&rbimpl_id, ("initialize")); }) : (rb_intern)("initialize")) && klass != rb_cObject && RB_TYPE_P(klass, RUBY_T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) {
((rb_classext_t *)((char *)(klass) + sizeof(struct RClass)))->max_iv_count = rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval);
}
if (!is_singleton && vm_scope_module_func_check(ec)) {
klass = rb_singleton_class(klass);
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
}
}
static VALUE
vm_invokeblock_i(struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *reg_cfp,
struct rb_calling_info *calling)
{
const struct rb_callinfo *ci = calling->ci;
VALUE block_handler = VM_CF_BLOCK_HANDLER((((reg_cfp))));
if (block_handler == 0) {
rb_vm_localjump_error("no block given (yield)", ((VALUE)RUBY_Qnil), 0);
}
else {
return vm_invoke_block(ec, (((reg_cfp))), calling, ci, 0, block_handler);
}
}
static const struct rb_callcache *
vm_search_method_wrap(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
{
return vm_search_method((VALUE)reg_cfp->iseq, cd, recv);
}
static const struct rb_callcache *
vm_search_invokeblock(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
{
static const struct rb_callcache cc = {
.flags = RUBY_T_IMEMO | (imemo_callcache << ((VALUE)RUBY_FL_USHIFT)) | ((VALUE)RUBY_FL_FREEZE),
.klass = 0,
.cme_ = 0,
.call_ = vm_invokeblock_i,
.aux_ = {0},
};
return &cc;
}
static
VALUE
vm_sendish(
struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *reg_cfp,
struct rb_call_data *cd,
VALUE block_handler,
const struct rb_callcache *(*method_explorer)(const struct rb_control_frame_struct *cfp, struct rb_call_data *cd, VALUE recv)
) {
VALUE val = ((VALUE)RUBY_Qundef);
const struct rb_callinfo *ci = cd->ci;
const struct rb_callcache *cc;
int argc = vm_ci_argc(ci);
VALUE recv = (*(((((reg_cfp)->sp)))-(argc)-1));
struct rb_calling_info calling = {
.block_handler = block_handler,
.kw_splat = (vm_ci_flag(ci) & (0x01 << VM_CALL_KW_SPLAT_bit)) > 0,
.recv = recv,
.argc = argc,
.ci = ci,
};
calling.cc = cc = method_explorer((((reg_cfp))), cd, recv);
val = vm_cc_call(cc)(ec, (((reg_cfp))), &calling);
if (!RB_UNDEF_P(val)) {
return val;
}
else {
do { (reg_cfp) = ec->cfp; } while (0);
}
if (((((((reg_cfp)))->iseq))->body)->catch_except_p) {
VM_ENV_FLAGS_SET(((((reg_cfp)->ep))), VM_FRAME_FLAG_FINISH);
return rb_vm_exec(ec, 1);
}
else if (RB_UNDEF_P(val = jit_exec(ec))) {
VM_ENV_FLAGS_SET(((((reg_cfp)->ep))), VM_FRAME_FLAG_FINISH);
return rb_vm_exec(ec, 0);
}
else {
return val;
}
}
VALUE rb_nil_to_s(VALUE);
VALUE rb_true_to_s(VALUE);
VALUE rb_false_to_s(VALUE);
VALUE rb_int_to_s(int argc, VALUE *argv, VALUE x);
VALUE rb_fix_to_s(VALUE);
VALUE rb_mod_to_s(VALUE);
VALUE rb_mod_name(VALUE);
static VALUE
vm_objtostring(const rb_iseq_t *iseq, VALUE recv, CALL_DATA cd)
{
int type = ((int)rb_type(recv));
if (type == RUBY_T_STRING) {
return recv;
}
const struct rb_callcache *cc = vm_search_method((VALUE)iseq, cd, recv);
switch (type) {
case RUBY_T_SYMBOL:
if (check_cfunc(vm_cc_cme(cc), rb_sym_to_s)) {
return rb_sym2str(recv);
}
break;
case RUBY_T_MODULE:
case RUBY_T_CLASS:
if (check_cfunc(vm_cc_cme(cc), rb_mod_to_s)) {
VALUE val = rb_mod_name(recv);
if (RB_NIL_P(val)) {
val = rb_mod_to_s(recv);
}
return val;
}
break;
case RUBY_T_NIL:
if (check_cfunc(vm_cc_cme(cc), rb_nil_to_s)) {
return rb_nil_to_s(recv);
}
break;
case RUBY_T_TRUE:
if (check_cfunc(vm_cc_cme(cc), rb_true_to_s)) {
return rb_true_to_s(recv);
}
break;
case RUBY_T_FALSE:
if (check_cfunc(vm_cc_cme(cc), rb_false_to_s)) {
return rb_false_to_s(recv);
}
break;
case RUBY_T_FIXNUM:
if (check_cfunc(vm_cc_cme(cc), rb_int_to_s)) {
return rb_fix_to_s(recv);
}
break;
}
return ((VALUE)RUBY_Qundef);
}
static VALUE
vm_opt_str_freeze(VALUE str, int bop, ID id)
{
if (((__builtin_expect(!!((ruby_vm_redefined_flag[(bop)]&((1 << 2))) == 0), 1)))) {
return str;
}
else {
return ((VALUE)RUBY_Qundef);
}
}
static VALUE
vm_opt_newarray_max(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
{
if (((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MAX)]&((1 << 3))) == 0), 1)))) {
if (num == 0) {
return ((VALUE)RUBY_Qnil);
}
else {
VALUE result = *ptr;
rb_snum_t i = num - 1;
while (i-- > 0) {
const VALUE v = *++ptr;
if (((RB_FIXNUM_P(v) && RB_FIXNUM_P(result) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 0))) == 0), 1)))) ? (((long)v > (long)result) ? 1 : ((long)v < (long)result) ? -1 : 0) : ((RB_TYPE_P((v), RUBY_T_STRING) && rb_class_of(v) == rb_cString) && (RB_TYPE_P((result), RUBY_T_STRING) && rb_class_of(result) == rb_cString) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 2))) == 0), 1)))) ? rb_str_cmp(v, result) : (RB_FLOAT_TYPE_P(v) && RB_FLOAT_TYPE_P(result) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 1))) == 0), 1)))) ? rb_float_cmp(v, result) : rb_cmpint(rb_funcallv(v, idCmp, 1, &result), v, result)) > 0) {
result = v;
}
}
return result;
}
}
else {
return rb_vm_call_with_refinements(ec, rb_ary_new_from_values(num, ptr), idMax, 0, ((void *)0), 0);
}
}static inline
VALUE
rb_vm_opt_newarray_max(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
{
return vm_opt_newarray_max(ec, num, ptr);
}
static VALUE
vm_opt_newarray_min(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
{
if (((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MIN)]&((1 << 3))) == 0), 1)))) {
if (num == 0) {
return ((VALUE)RUBY_Qnil);
}
else {
VALUE result = *ptr;
rb_snum_t i = num - 1;
while (i-- > 0) {
const VALUE v = *++ptr;
if (((RB_FIXNUM_P(v) && RB_FIXNUM_P(result) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 0))) == 0), 1)))) ? (((long)v > (long)result) ? 1 : ((long)v < (long)result) ? -1 : 0) : ((RB_TYPE_P((v), RUBY_T_STRING) && rb_class_of(v) == rb_cString) && (RB_TYPE_P((result), RUBY_T_STRING) && rb_class_of(result) == rb_cString) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 2))) == 0), 1)))) ? rb_str_cmp(v, result) : (RB_FLOAT_TYPE_P(v) && RB_FLOAT_TYPE_P(result) && ((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_CMP)]&((1 << 1))) == 0), 1)))) ? rb_float_cmp(v, result) : rb_cmpint(rb_funcallv(v, idCmp, 1, &result), v, result)) < 0) {
result = v;
}
}
return result;
}
}
else {
return rb_vm_call_with_refinements(ec, rb_ary_new_from_values(num, ptr), idMin, 0, ((void *)0), 0);
}
}static inline
VALUE
rb_vm_opt_newarray_min(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
{
return vm_opt_newarray_min(ec, num, ptr);
}
static void
vm_track_constant_cache(ID id, void *ic)
{
rb_vm_t *vm = rb_current_vm();
struct rb_id_table *const_cache = vm->constant_cache;
VALUE lookup_result;
st_table *ics;
if (rb_id_table_lookup(const_cache, id, &lookup_result)) {
ics = (st_table *)lookup_result;
}
else {
ics = rb_st_init_numtable();
rb_id_table_insert(const_cache, id, (VALUE)ics);
}
vm->inserting_constant_cache_id = id;
rb_st_insert(ics, (st_data_t) ic, (st_data_t) ((VALUE)RUBY_Qtrue));
vm->inserting_constant_cache_id = (ID)0;
}
static void
vm_ic_track_const_chain(rb_control_frame_t *cfp, IC ic, const ID *segments)
{
{ unsigned int _lev; rb_vm_lock_enter(&_lev, "./vm_insnhelper.c", 5320);;
for (int i = 0; segments[i]; i++) {
ID id = segments[i];
if (id == idNULL) continue;
vm_track_constant_cache(id, ic);
}
rb_vm_lock_leave(&_lev, "./vm_insnhelper.c", 5328); };
}
static inline _Bool
vm_inlined_ic_hit_p(VALUE flags, VALUE value, const rb_cref_t *ic_cref, const VALUE *reg_ep)
{
if ((flags & ((VALUE)RUBY_FL_USER4)) || rb_ractor_main_p()) {
((void)0);
return (ic_cref == ((void *)0) ||
ic_cref == vm_get_cref(reg_ep));
}
return 0;
}
static _Bool
vm_ic_hit_p(const struct iseq_inline_constant_cache_entry *ice, const VALUE *reg_ep)
{
((void)0);
return vm_inlined_ic_hit_p(ice->flags, ice->value, ice->ic_cref, reg_ep);
}static inline
_Bool
rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep)
{
return ic->entry && vm_ic_hit_p(ic->entry, reg_ep);
}
COLDFUNC static void
vm_ic_update(const rb_iseq_t *iseq, IC ic, VALUE val, const VALUE *reg_ep, const VALUE *pc) {
if (ruby_vm_const_missing_count > 0) {
ruby_vm_const_missing_count = 0;
ic->entry = ((void *)0);
return;
}
struct iseq_inline_constant_cache_entry *ice = (struct iseq_inline_constant_cache_entry *)rb_imemo_new(imemo_constcache, 0, 0, 0, 0);
rb_obj_write((VALUE)(ice), ((VALUE *)(&ice->value)), (VALUE)(val), "./vm_insnhelper.c", 5368);
ice->ic_cref = vm_get_const_key_cref(reg_ep);
if (rb_ractor_shareable_p(val)) ice->flags |= ((VALUE)RUBY_FL_USER4);
rb_obj_write((VALUE)(iseq), ((VALUE *)(&ic->entry)), (VALUE)(ice), "./vm_insnhelper.c", 5371);
((void)0);
unsigned pos = (unsigned)(pc - ((iseq)->body)->iseq_encoded);
rb_yjit_constant_ic_update(iseq, ic, pos);
rb_mjit_constant_ic_update(iseq, ic, pos);
}
static VALUE
vm_once_dispatch(rb_execution_context_t *ec, ISEQ iseq, ISE is)
{
rb_thread_t *th = rb_ec_thread_ptr(ec);
rb_thread_t *const RUNNING_THREAD_ONCE_DONE = (rb_thread_t *)(0x1);
again:
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {
return is->once.value;
}
else if (is->once.running_thread == ((void *)0)) {
VALUE val;
is->once.running_thread = th;
val = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
rb_obj_write((VALUE)(ec->cfp->iseq), ((VALUE *)(&is->once.value)), (VALUE)(val), "./vm_insnhelper.c", 5393);
is->once.running_thread = RUNNING_THREAD_ONCE_DONE;
return val;
}
else if (is->once.running_thread == th) {
return vm_once_exec((VALUE)iseq);
}
else {
rb_vm_check_ints(ec);
rb_thread_schedule();
goto again;
}
}
static OFFSET
vm_case_dispatch(CDHASH hash, OFFSET else_offset, VALUE key)
{
switch (__extension__({ VALUE arg_obj = (key); RB_SPECIAL_CONST_P(arg_obj) ? -1 : (int)RB_BUILTIN_TYPE(arg_obj); })) {
case -1:
case RUBY_T_FLOAT:
case RUBY_T_SYMBOL:
case RUBY_T_BIGNUM:
case RUBY_T_STRING:
if (((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_EQQ)]&((1 << 6) | (1 << 0) | (1 << 1) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 2))) == 0), 1)))) {
st_data_t val;
if (RB_FLOAT_TYPE_P(key)) {
double kval = rb_float_value_inline(key);
if (!__builtin_isinf_sign (kval) && modf(kval, &kval) == 0.0) {
key = (((kval) < (0x7fffffffffffffffL / 2) + 1) && ((kval) >= ((-0x7fffffffffffffffL - 1L) / 2))) ? RB_INT2FIX((long)kval) : rb_dbl2big(kval);
}
}
if (rb_hash_stlike_lookup(hash, key, &val)) {
return rb_fix2long((VALUE)val);
}
else {
return else_offset;
}
}
}
return 0;
}
__attribute__((__noreturn__)) static void vm_stack_consistency_error(const rb_execution_context_t *ec, const rb_control_frame_t *, const VALUE *);
static void
vm_stack_consistency_error(const rb_execution_context_t *ec,
const rb_control_frame_t *cfp,
const VALUE *bp)
{
const ptrdiff_t nsp = ((cfp->sp) - (ec)->vm_stack);
const ptrdiff_t nbp = ((bp) - (ec)->vm_stack);
static const char stack_consistency_error[] =
"Stack consistency error (sp: %""t""d"", bp: %""t""d"")";
rb_bug(stack_consistency_error, nsp, nbp);
}
ALWAYS_INLINE(static inline VALUE
vm_opt_plus(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_plus(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_PLUS)]&((1 << 0))) == 0), 1)))) {
return rb_fix_plus_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_PLUS)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) + rb_float_value_inline(obj));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_PLUS)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) + rb_float_value_inline(obj));
}
else if (RBASIC_CLASS(recv) == rb_cString &&
RBASIC_CLASS(obj) == rb_cString &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_PLUS)]&((1 << 2))) == 0), 1)))) {
return rb_str_opt_plus(recv, obj);
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
RBASIC_CLASS(obj) == rb_cArray &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_PLUS)]&((1 << 3))) == 0), 1)))) {
return rb_ary_plus(recv, obj);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_minus(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_minus(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MINUS)]&((1 << 0))) == 0), 1)))) {
return rb_fix_minus_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MINUS)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) - rb_float_value_inline(obj));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MINUS)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) - rb_float_value_inline(obj));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_mult(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_mult(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MULT)]&((1 << 0))) == 0), 1)))) {
return rb_fix_mul_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MULT)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) * rb_float_value_inline(obj));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MULT)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(rb_float_value_inline(recv) * rb_float_value_inline(obj));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_div(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_div(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_DIV)]&((1 << 0))) == 0), 1)))) {
return (rb_fix2long(obj) == 0) ? ((VALUE)RUBY_Qundef) : rb_fix_div_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_DIV)]&((1 << 1))) == 0), 1)))) {
return rb_flo_div_flo(recv, obj);
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_DIV)]&((1 << 1))) == 0), 1)))) {
return rb_flo_div_flo(recv, obj);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_mod(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_mod(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MOD)]&((1 << 0))) == 0), 1)))) {
return (rb_fix2long(obj) == 0) ? ((VALUE)RUBY_Qundef) : rb_fix_mod_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MOD)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(ruby_float_mod(rb_float_value_inline(recv), rb_float_value_inline(obj)));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MOD)]&((1 << 1))) == 0), 1)))) {
return rb_float_new_inline(ruby_float_mod(rb_float_value_inline(recv), rb_float_value_inline(obj)));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_neq(const rb_iseq_t *iseq, CALL_DATA cd, CALL_DATA cd_eq, VALUE recv, VALUE obj));
static inline VALUE
vm_opt_neq(const rb_iseq_t *iseq, CALL_DATA cd, CALL_DATA cd_eq, VALUE recv, VALUE obj) {
if (vm_method_cfunc_is(iseq, cd, recv, rb_obj_not_equal)) {
VALUE val = opt_equality(iseq, recv, obj, cd_eq);
if (!RB_UNDEF_P(val)) {
return ((!RB_TEST(val)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
}
return ((VALUE)RUBY_Qundef);
}
ALWAYS_INLINE(static inline VALUE
vm_opt_lt(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_lt(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LT)]&((1 << 0))) == 0), 1)))) {
return (((long)recv < (long)obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LT)]&((1 << 1))) == 0), 1)))) {
return ((rb_float_value_inline(recv) < rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LT)]&((1 << 1))) == 0), 1)))) {
;
return ((rb_float_value_inline(recv) < rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_le(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_le(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LE)]&((1 << 0))) == 0), 1)))) {
return (((long)recv <= (long)obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LE)]&((1 << 1))) == 0), 1)))) {
return ((rb_float_value_inline(recv) <= rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LE)]&((1 << 1))) == 0), 1)))) {
;
return ((rb_float_value_inline(recv) <= rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_gt(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_gt(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GT)]&((1 << 0))) == 0), 1)))) {
return (((long)recv > (long)obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GT)]&((1 << 1))) == 0), 1)))) {
return ((rb_float_value_inline(recv) > rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GT)]&((1 << 1))) == 0), 1)))) {
;
return ((rb_float_value_inline(recv) > rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_ge(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_ge(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GE)]&((1 << 0))) == 0), 1)))) {
return (((long)recv >= (long)obj) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (FLONUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GE)]&((1 << 1))) == 0), 1)))) {
return ((rb_float_value_inline(recv) >= rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else if (RB_SPECIAL_CONST_P(recv) || RB_SPECIAL_CONST_P(obj)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_GE)]&((1 << 1))) == 0), 1)))) {
;
return ((rb_float_value_inline(recv) >= rb_float_value_inline(obj)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_ltlt(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_ltlt(VALUE recv, VALUE obj) {
if (RB_SPECIAL_CONST_P(recv)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cString &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LTLT)]&((1 << 2))) == 0), 1)))) {
if ((__builtin_expect(!!(RB_TYPE_P(obj, RUBY_T_STRING)), 1))) {
return rb_str_buf_append(recv, obj);
}
else {
return rb_str_concat(recv, obj);
}
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_LTLT)]&((1 << 3))) == 0), 1)))) {
return rb_ary_push(recv, obj);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_and(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_and(VALUE recv, VALUE obj) {
VALUE ret = ((long) recv) & ((long) obj);
if (RB_FIXNUM_P(ret) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_AND)]&((1 << 0))) == 0), 1)))) {
return ret;
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_or(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_or(VALUE recv, VALUE obj) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_OR)]&((1 << 0))) == 0), 1)))) {
return recv | obj;
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_aref(VALUE recv, VALUE obj));
static inline VALUE
vm_opt_aref(VALUE recv, VALUE obj) {
if (RB_SPECIAL_CONST_P(recv)) {
if (FIXNUM_2_P(recv, obj) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_AREF)]&((1 << 0))) == 0), 1)))) {
return rb_fix_aref(recv, obj);
}
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_AREF)]&((1 << 3))) == 0), 1)))) {
if (RB_FIXNUM_P(obj)) {
return rb_ary_entry_internal(recv, rb_fix2long(obj));
}
else {
return rb_ary_aref1(recv, obj);
}
}
else if (RBASIC_CLASS(recv) == rb_cHash &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_AREF)]&((1 << 4))) == 0), 1)))) {
return rb_hash_aref(recv, obj);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_aset(VALUE recv, VALUE obj, VALUE set));
static inline VALUE
vm_opt_aset(VALUE recv, VALUE obj, VALUE set) {
if (RB_SPECIAL_CONST_P(recv)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_ASET)]&((1 << 3))) == 0), 1))) &&
RB_FIXNUM_P(obj)) {
rb_ary_store(recv, rb_fix2long(obj), set);
return set;
}
else if (RBASIC_CLASS(recv) == rb_cHash &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_ASET)]&((1 << 4))) == 0), 1)))) {
rb_hash_aset(recv, obj, set);
return set;
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_aref_with(VALUE recv, VALUE key));
static inline VALUE
vm_opt_aref_with(VALUE recv, VALUE key) {
if (!RB_SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_AREF)]&((1 << 4))) == 0), 1))) &&
rb_hash_compare_by_id_p(recv) == ((VALUE)RUBY_Qfalse) &&
!RB_FL_TEST(recv, RHASH_PROC_DEFAULT)) {
return rb_hash_aref(recv, key);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_aset_with(VALUE recv, VALUE key, VALUE val));
static inline VALUE
vm_opt_aset_with(VALUE recv, VALUE key, VALUE val) {
if (!RB_SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_ASET)]&((1 << 4))) == 0), 1))) &&
rb_hash_compare_by_id_p(recv) == ((VALUE)RUBY_Qfalse)) {
return rb_hash_aset(recv, key, val);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
static VALUE
vm_opt_length(VALUE recv, int bop)
{
if (RB_SPECIAL_CONST_P(recv)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cString &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(bop)]&((1 << 2))) == 0), 1)))) {
if (bop == BOP_EMPTY_P) {
return rb_long2num_inline(RSTRING_LEN(recv));
}
else {
return rb_str_length(recv);
}
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(bop)]&((1 << 3))) == 0), 1)))) {
return rb_long2num_inline(rb_array_len(recv));
}
else if (RBASIC_CLASS(recv) == rb_cHash &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(bop)]&((1 << 4))) == 0), 1)))) {
return __builtin_choose_expr( __builtin_constant_p(RHASH_SIZE(recv)), ((VALUE)(RHASH_SIZE(recv))) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(RHASH_SIZE(recv)));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
static VALUE
vm_opt_empty_p(VALUE recv)
{
switch (vm_opt_length(recv, BOP_EMPTY_P)) {
case ((VALUE)RUBY_Qundef): return ((VALUE)RUBY_Qundef);
case __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0)): return ((VALUE)RUBY_Qtrue);
default: return ((VALUE)RUBY_Qfalse);
}
}
VALUE rb_false(VALUE obj);
static VALUE
vm_opt_nil_p(const rb_iseq_t *iseq, CALL_DATA cd, VALUE recv)
{
if (RB_NIL_P(recv) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_NIL_P)]&((1 << 9))) == 0), 1)))) {
return ((VALUE)RUBY_Qtrue);
}
else if (vm_method_cfunc_is(iseq, cd, recv, rb_false)) {
return ((VALUE)RUBY_Qfalse);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
static VALUE
fix_succ(VALUE x)
{
switch (x) {
case ~0UL:
return __builtin_choose_expr( __builtin_constant_p(0), ((VALUE)(0)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(0));
case ((~0UL)>>(int)(1)):
return rb_uint2big(1UL << (8 * 8 - 2));
default:
return x + 2;
}
}
static VALUE
vm_opt_succ(VALUE recv)
{
if (RB_FIXNUM_P(recv) &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_SUCC)]&((1 << 0))) == 0), 1)))) {
return fix_succ(recv);
}
else if (RB_SPECIAL_CONST_P(recv)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cString &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_SUCC)]&((1 << 2))) == 0), 1)))) {
return rb_str_succ(recv);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
ALWAYS_INLINE(static inline VALUE
vm_opt_not(const rb_iseq_t *iseq, CALL_DATA cd, VALUE recv));
static inline VALUE
vm_opt_not(const rb_iseq_t *iseq, CALL_DATA cd, VALUE recv) {
if (vm_method_cfunc_is(iseq, cd, recv, rb_obj_not)) {
return ((!RB_TEST(recv)) ? ((VALUE)RUBY_Qtrue) : ((VALUE)RUBY_Qfalse));
}
else {
return ((VALUE)RUBY_Qundef);
}
}
static VALUE
vm_opt_regexpmatch2(VALUE recv, VALUE obj)
{
if (RB_SPECIAL_CONST_P(recv)) {
return ((VALUE)RUBY_Qundef);
}
else if (RBASIC_CLASS(recv) == rb_cString &&
rb_class_of(obj) == rb_cRegexp &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MATCH)]&((1 << 2))) == 0), 1)))) {
return rb_reg_match(obj, recv);
}
else if (RBASIC_CLASS(recv) == rb_cRegexp &&
((__builtin_expect(!!((ruby_vm_redefined_flag[(BOP_MATCH)]&((1 << 8))) == 0), 1)))) {
return rb_reg_match(recv, obj);
}
else {
return ((VALUE)RUBY_Qundef);
}
}
rb_event_flag_t rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos);
__attribute__((__noinline__)) static void vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp);
static inline void
vm_trace_hook(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE *pc,
rb_event_flag_t pc_events, rb_event_flag_t target_event,
rb_hook_list_t *global_hooks, rb_hook_list_t *const *local_hooks_ptr, VALUE val)
{
rb_event_flag_t event = pc_events & target_event;
VALUE self = (((((reg_cfp)))->self));
((void)0);
if (event & global_hooks->events) {
reg_cfp->pc++;
vm_dtrace(event, ec);
rb_exec_event_hook_orig(ec, global_hooks, event, self, 0, 0, 0 , val, 0);
reg_cfp->pc--;
}
rb_hook_list_t *local_hooks = *local_hooks_ptr;
if (local_hooks != ((void *)0)) {
if (event & local_hooks->events) {
reg_cfp->pc++;
rb_exec_event_hook_orig(ec, local_hooks, event, self, 0, 0, 0 , val, 0);
reg_cfp->pc--;
}
}
}static inline
_Bool
rb_vm_opt_cfunc_p(CALL_CACHE cc, int insn)
{
switch (insn) {
case YARVINSN_opt_eq:
return check_cfunc(vm_cc_cme(cc), rb_obj_equal);
case YARVINSN_opt_nil_p:
return check_cfunc(vm_cc_cme(cc), rb_false);
case YARVINSN_opt_not:
return check_cfunc(vm_cc_cme(cc), rb_obj_not);
default:
return 0;
}
}
static void
vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)
{
const VALUE *pc = reg_cfp->pc;
rb_event_flag_t enabled_flags = ruby_vm_event_flags & (0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010| 0x0020| 0x0040| 0x0100| 0x0200| 0x010000| 0x020000);
rb_event_flag_t global_events = enabled_flags;
if (enabled_flags == 0 && ruby_vm_event_local_num == 0) {
return;
}
else {
const rb_iseq_t *iseq = reg_cfp->iseq;
VALUE iseq_val = (VALUE)iseq;
size_t pos = pc - ((iseq)->body)->iseq_encoded;
rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pos);
rb_hook_list_t *local_hooks = iseq->aux.exec.local_hooks;
rb_hook_list_t *const *local_hooks_ptr = &iseq->aux.exec.local_hooks;
rb_event_flag_t iseq_local_events = local_hooks != ((void *)0) ? local_hooks->events : 0;
rb_hook_list_t *bmethod_local_hooks = ((void *)0);
rb_hook_list_t **bmethod_local_hooks_ptr = ((void *)0);
rb_event_flag_t bmethod_local_events = 0;
const _Bool bmethod_frame = VM_FRAME_BMETHOD_P(reg_cfp);
enabled_flags |= iseq_local_events;
((void)0);
if (bmethod_frame) {
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(reg_cfp);
((void)0);
bmethod_local_hooks = me->def->body.bmethod.hooks;
bmethod_local_hooks_ptr = &me->def->body.bmethod.hooks;
if (bmethod_local_hooks) {
bmethod_local_events = bmethod_local_hooks->events;
}
}
if ((pc_events & enabled_flags) == 0 && !bmethod_frame) {
return;
}
else if (ec->trace_arg != ((void *)0)) {
return;
}
else {
rb_hook_list_t *global_hooks = rb_ec_ractor_hooks(ec);
rb_event_flag_t bmethod_events = global_events | bmethod_local_events;
if (0) {
ruby_debug_printf("vm_trace>>%4d (%4x) - %s:%d %s\n",
(int)pos,
(int)pc_events,
RSTRING_PTR(rb_iseq_path(iseq)),
(int)rb_iseq_line_no(iseq, pos),
RSTRING_PTR(rb_iseq_label(iseq)));
}
((void)0);
((void)0);
if ((pc_events & 0x0100) && bmethod_frame && (bmethod_events & 0x0008)) {
vm_trace_hook(ec, reg_cfp, pc, 0x0008, 0x0008, global_hooks, bmethod_local_hooks_ptr, ((VALUE)RUBY_Qundef));
}
do { if ((pc_events & (0x0002 | 0x0008 | 0x0100)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (0x0002 | 0x0008 | 0x0100), global_hooks, local_hooks_ptr, (((VALUE)RUBY_Qundef))); } } while (0);
do { if ((pc_events & (0x0001)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (0x0001), global_hooks, local_hooks_ptr, (((VALUE)RUBY_Qundef))); } } while (0);
do { if ((pc_events & (0x010000)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (0x010000), global_hooks, local_hooks_ptr, (((VALUE)RUBY_Qundef))); } } while (0);
do { if ((pc_events & (0x020000)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (0x020000), global_hooks, local_hooks_ptr, (((VALUE)RUBY_Qundef))); } } while (0);
do { if ((pc_events & (0x0004 | 0x0010 | 0x0200)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (0x0004 | 0x0010 | 0x0200), global_hooks, local_hooks_ptr, ((*(((((reg_cfp)->sp)))-(0)-1)))); } } while (0);
if ((pc_events & 0x0200) && bmethod_frame && (bmethod_events & 0x0010)) {
vm_trace_hook(ec, reg_cfp, pc, 0x0010, 0x0010, global_hooks, bmethod_local_hooks_ptr, (*(((((reg_cfp)->sp)))-(0)-1)));
}
(*__extension__ ({ volatile VALUE *rb_gc_guarded_ptr = &(iseq_val); __asm__("" : : "m"(rb_gc_guarded_ptr)); rb_gc_guarded_ptr; }));
}
}
}static inline
void Init_vm_stack_canary(void) { }
static VALUE
builtin_invoker0(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr0_t)(rb_execution_context_t *ec, VALUE self);
return (*(rb_invoke_funcptr0_t)funcptr)(ec, self);
}
static VALUE
builtin_invoker1(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr1_t)(rb_execution_context_t *ec, VALUE self, VALUE v1);
return (*(rb_invoke_funcptr1_t)funcptr)(ec, self, argv[0]);
}
static VALUE
builtin_invoker2(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr2_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2);
return (*(rb_invoke_funcptr2_t)funcptr)(ec, self, argv[0], argv[1]);
}
static VALUE
builtin_invoker3(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr3_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3);
return (*(rb_invoke_funcptr3_t)funcptr)(ec, self, argv[0], argv[1], argv[2]);
}
static VALUE
builtin_invoker4(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr4_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4);
return (*(rb_invoke_funcptr4_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3]);
}
static VALUE
builtin_invoker5(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr5_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5);
return (*(rb_invoke_funcptr5_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
static VALUE
builtin_invoker6(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr6_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6);
return (*(rb_invoke_funcptr6_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}
static VALUE
builtin_invoker7(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr7_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7);
return (*(rb_invoke_funcptr7_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}
static VALUE
builtin_invoker8(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr8_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8);
return (*(rb_invoke_funcptr8_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}
static VALUE
builtin_invoker9(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr9_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9);
return (*(rb_invoke_funcptr9_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
}
static VALUE
builtin_invoker10(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr10_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10);
return (*(rb_invoke_funcptr10_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
}
static VALUE
builtin_invoker11(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr11_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10, VALUE v11);
return (*(rb_invoke_funcptr11_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
}
static VALUE
builtin_invoker12(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr12_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10, VALUE v11, VALUE v12);
return (*(rb_invoke_funcptr12_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
}
static VALUE
builtin_invoker13(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr13_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10, VALUE v11, VALUE v12, VALUE v13);
return (*(rb_invoke_funcptr13_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]);
}
static VALUE
builtin_invoker14(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr14_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10, VALUE v11, VALUE v12, VALUE v13, VALUE v14);
return (*(rb_invoke_funcptr14_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
}
static VALUE
builtin_invoker15(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
{
typedef VALUE (*rb_invoke_funcptr15_t)(rb_execution_context_t *ec, VALUE self, VALUE v1, VALUE v2, VALUE v3, VALUE v4, VALUE v5, VALUE v6, VALUE v7, VALUE v8, VALUE v9, VALUE v10, VALUE v11, VALUE v12, VALUE v13, VALUE v14, VALUE v15);
return (*(rb_invoke_funcptr15_t)funcptr)(ec, self, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]);
}
typedef VALUE (*builtin_invoker)(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr);
static builtin_invoker
lookup_builtin_invoker(int argc)
{
static const builtin_invoker invokers[] = {
builtin_invoker0,
builtin_invoker1,
builtin_invoker2,
builtin_invoker3,
builtin_invoker4,
builtin_invoker5,
builtin_invoker6,
builtin_invoker7,
builtin_invoker8,
builtin_invoker9,
builtin_invoker10,
builtin_invoker11,
builtin_invoker12,
builtin_invoker13,
builtin_invoker14,
builtin_invoker15,
};
return invokers[argc];
}
static inline VALUE
invoke_bf(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const struct rb_builtin_function* bf, const VALUE *argv)
{
const _Bool canary_p = ((reg_cfp->iseq)->body)->builtin_inline_p;
if (canary_p) {} else {};
VALUE ret = (*lookup_builtin_invoker(bf->argc))(ec, reg_cfp->self, argv, (rb_insn_func_t)bf->func_ptr);
if (canary_p) {(void)(YARVINSN_invokebuiltin);};
return ret;
}
static VALUE
vm_invoke_builtin(rb_execution_context_t *ec, rb_control_frame_t *cfp, const struct rb_builtin_function* bf, const VALUE *argv)
{
return invoke_bf(ec, cfp, bf, argv);
}
static VALUE
vm_invoke_builtin_delegate(rb_execution_context_t *ec, rb_control_frame_t *cfp, const struct rb_builtin_function *bf, unsigned int start_index)
{
if (0) {
fputs("vm_invoke_builtin_delegate: passing -> ", stderr);
for (int i=0; i<bf->argc; i++) {
ruby_debug_printf(":%s ", rb_id2name(((cfp->iseq)->body)->local_table[i+start_index]));
}
ruby_debug_printf("\n" "%s %s(%d):%p\n", __func__, bf->name, bf->argc, bf->func_ptr);
}
if (bf->argc == 0) {
return invoke_bf(ec, cfp, bf, ((void *)0));
}
else {
const VALUE *argv = cfp->ep - ((cfp->iseq)->body)->local_table_size - ( 3) + 1 + start_index;
return invoke_bf(ec, cfp, bf, argv);
}
}static inline
VALUE
rb_vm_lvar_exposed(rb_execution_context_t *ec, int index)
{
const rb_control_frame_t *cfp = ec->cfp;
return cfp->ep[index];
}
struct local_var_list {
VALUE tbl;
};
static inline VALUE method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status, int kw_splat);
static inline VALUE vm_yield_with_cref(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat, const rb_cref_t *cref, int is_lambda);
static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_splat);
static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler, int kw_splat);
static inline VALUE vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args);
VALUE rb_vm_exec(rb_execution_context_t *ec, _Bool jit_enable_p);
static void vm_set_eval_stack(rb_execution_context_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block);
static int vm_collect_local_variables_in_heap(const VALUE *dfp, const struct local_var_list *vars);
static VALUE rb_eUncaughtThrow;
static ID id_result, id_tag, id_value;
typedef enum call_type {
CALL_PUBLIC,
CALL_FCALL,
CALL_VCALL,
CALL_PUBLIC_KW,
CALL_FCALL_KW,
CALL_TYPE_MAX
} call_type;
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv);
static inline void
stack_check(rb_execution_context_t *ec)
{
if (!(((ec)->raised_flag & (RAISED_STACKOVERFLOW)) != 0) &&
rb_ec_stack_check(ec)) {
((ec)->raised_flag |= (RAISED_STACKOVERFLOW));
rb_ec_stack_overflow(ec, 0);
}
}
static void
raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
enum method_missing_reason last_call_status)
{
VALUE exc = rb_eNoMethodError;
VALUE format = 0;
if ((__builtin_expect(!!(argc == 0), 0))) {
rb_raise(rb_eArgError, "no method name given");
}
else if ((__builtin_expect(!!(!RB_SYMBOL_P(argv[0])), 0))) {
const VALUE e = rb_eArgError;
rb_raise(e, "method name must be a Symbol but %""l""i" "\v"" is given",
rb_obj_class(argv[0]));
}
stack_check(ec);
if (last_call_status & MISSING_PRIVATE) {
format = rb_fstring_new(("private method `%s' called for %s%s%s"), (sizeof("private method `%s' called for %s%s%s" "") - 1));
}
else if (last_call_status & MISSING_PROTECTED) {
format = rb_fstring_new(("protected method `%s' called for %s%s%s"), (sizeof("protected method `%s' called for %s%s%s" "") - 1));
}
else if (last_call_status & MISSING_VCALL) {
format = rb_fstring_new(("undefined local variable or method `%s' for %s%s%s"), (sizeof("undefined local variable or method `%s' for %s%s%s" "") - 1));
exc = rb_eNameError;
}
else if (last_call_status & MISSING_SUPER) {
format = rb_fstring_new(("super: no superclass method `%s' for %s%s%s"), (sizeof("super: no superclass method `%s' for %s%s%s" "") - 1));
}
{
exc = rb_make_no_method_exception(exc, format, obj, argc, argv,
last_call_status & (MISSING_FCALL|MISSING_VCALL));
if (!(last_call_status & MISSING_MISSING)) {
rb_vm_pop_cfunc_frame();
}
rb_exc_raise(exc);
}
}
static void
vm_raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv,
VALUE obj, int call_status)
{
vm_passed_block_handler_set(ec, 0);
raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
}
static inline VALUE
method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VALUE *argv, enum method_missing_reason call_status, int kw_splat)
{
VALUE *nargv, result, work, klass;
VALUE block_handler = vm_passed_block_handler(ec);
const rb_callable_method_entry_t *me;
ec->method_missing_reason = call_status;
if (id == idMethodMissing) {
goto missing;
}
nargv = ((VALUE *) (((size_t)(argc + 1) < 1024 / sizeof(VALUE)) ? ((work) = 0, __builtin_alloca ((argc + 1) * sizeof(VALUE))) : rb_alloc_tmp_buffer2(&(work), (argc + 1), sizeof(VALUE))));
nargv[0] = rb_id2sym(id);
if (!argv) {
static const VALUE buf = ((VALUE)RUBY_Qfalse);
((void)0);
argv = &buf;
}
ruby_nonempty_memcpy((nargv + 1), (argv), rbimpl_size_mul_or_raise(sizeof(VALUE), (argc)));
++argc;
argv = nargv;
klass = rb_class_of(obj);
if (!klass) goto missing;
me = rb_callable_method_entry(klass, idMethodMissing);
if (!me || (int) (((me)->flags & (((VALUE)RUBY_FL_USER6) )) >> ((((VALUE)RUBY_FL_USHIFT) + 4)+2))) goto missing;
vm_passed_block_handler_set(ec, block_handler);
result = rb_vm_call_kw(ec, obj, idMethodMissing, argc, argv, me, kw_splat);
if (work) rb_free_tmp_buffer(&(work));
return result;
missing:
raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING);
__builtin_unreachable();
}
static rb_control_frame_t *
vm_get_ruby_level_caller_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
{
if (VM_FRAME_RUBYFRAME_P(cfp)) {
return (rb_control_frame_t *)cfp;
}
cfp = ((cfp)+1);
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)) {
if (VM_FRAME_RUBYFRAME_P(cfp)) {
return (rb_control_frame_t *)cfp;
}
if (VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_PASSED) == 0) {
break;
}
cfp = ((cfp)+1);
}
return 0;
}
static void
rb_vm_pop_cfunc_frame(void)
{
rb_execution_context_t *ec = rb_current_execution_context(1);
rb_control_frame_t *cfp = ec->cfp;
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
do { const rb_event_flag_t flag_arg_ = (0x0040); rb_hook_list_t *hooks_arg_ = (rb_ec_ractor_hooks(ec)); if ((__builtin_expect(!!((hooks_arg_)->events & (flag_arg_)), 0))) { rb_exec_event_hook_orig(ec, hooks_arg_, flag_arg_, cfp->self, me->def->original_id, me->called_id, me->owner, ((VALUE)RUBY_Qnil), 0); } } while (0);
do { if ((__builtin_expect(!!(0), 0))) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, me->owner, me->def->original_id, &args)) { do {} while (0); } } } while (0);
vm_pop_frame(ec, cfp, cfp->ep);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_0locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 0);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_1locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 1);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_2locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 2);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_3locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 3);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_4locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 4);
}
static VALUE
vm_call_iseq_setup_normal_0start_0params_5locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 0, 5);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_0locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 0);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_1locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 1);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_2locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 2);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_3locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 3);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_4locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 4);
}
static VALUE
vm_call_iseq_setup_normal_0start_1params_5locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 1, 5);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_0locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 0);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_1locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 1);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_2locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 2);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_3locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 3);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_4locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 4);
}
static VALUE
vm_call_iseq_setup_normal_0start_2params_5locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 2, 5);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_0locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 0);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_1locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 1);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_2locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 2);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_3locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 3);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_4locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 4);
}
static VALUE
vm_call_iseq_setup_normal_0start_3params_5locals(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_calling_info *calling)
{
((void)0);
return vm_call_iseq_setup_normal(ec, cfp, calling, vm_cc_cme(calling->cc), 0, 3, 5);
}
static const vm_call_handler vm_call_iseq_handlers[][6] = {
{
vm_call_iseq_setup_normal_0start_0params_0locals,
vm_call_iseq_setup_normal_0start_0params_1locals,
vm_call_iseq_setup_normal_0start_0params_2locals,
vm_call_iseq_setup_normal_0start_0params_3locals,
vm_call_iseq_setup_normal_0start_0params_4locals,
vm_call_iseq_setup_normal_0start_0params_5locals,
},
{
vm_call_iseq_setup_normal_0start_1params_0locals,
vm_call_iseq_setup_normal_0start_1params_1locals,
vm_call_iseq_setup_normal_0start_1params_2locals,
vm_call_iseq_setup_normal_0start_1params_3locals,
vm_call_iseq_setup_normal_0start_1params_4locals,
vm_call_iseq_setup_normal_0start_1params_5locals,
},
{
vm_call_iseq_setup_normal_0start_2params_0locals,
vm_call_iseq_setup_normal_0start_2params_1locals,
vm_call_iseq_setup_normal_0start_2params_2locals,
vm_call_iseq_setup_normal_0start_2params_3locals,
vm_call_iseq_setup_normal_0start_2params_4locals,
vm_call_iseq_setup_normal_0start_2params_5locals,
},
{
vm_call_iseq_setup_normal_0start_3params_0locals,
vm_call_iseq_setup_normal_0start_3params_1locals,
vm_call_iseq_setup_normal_0start_3params_2locals,
vm_call_iseq_setup_normal_0start_3params_3locals,
vm_call_iseq_setup_normal_0start_3params_4locals,
vm_call_iseq_setup_normal_0start_3params_5locals,
},
};
static inline vm_call_handler
vm_call_iseq_setup_func(const struct rb_callinfo *ci, const int param_size, const int local_size)
{
if ((__builtin_expect(!!(vm_ci_flag(ci) & (0x01 << VM_CALL_TAILCALL_bit)), 0))) {
return &vm_call_iseq_setup_tailcall_0start;
}
else if (0) {
return &vm_call_iseq_setup_normal_0start;
}
else if (param_size <= 3 && local_size <= 5) {
((void)0);
return vm_call_iseq_handlers[param_size][local_size];
}
else {
return &vm_call_iseq_setup_normal_0start;
}
}
#define MJIT_HEADER 1
#undef _FORTIFY_SOURCE
#define _FORTIFY_SOURCE 2
#define RUBY_EXPORT 1
#define _FORTIFY_SOURCE 2
#define _GLIBCXX_ASSERTIONS 1
#define _STDC_PREDEF_H 1
#define __STDC_IEC_559__ 1
#define __STDC_IEC_559_COMPLEX__ 1
#define __STDC_ISO_10646__ 201706L
#define vm_exec rb_vm_exec
#define RUBY_EVAL_INTERN_H
#define RUBY_RUBY_H 1
#define RBIMPL_CONFIG_H
#define INCLUDE_RUBY_CONFIG_H 1
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_PTHREAD_SEMANTICS 1
#define _TANDEM_SOURCE 1
#define RUBY_SYMBOL_EXPORT_BEGIN _Pragma("GCC visibility push(default)")
#define RUBY_SYMBOL_EXPORT_END _Pragma("GCC visibility pop")
#define HAVE_STMT_AND_DECL_IN_EXPR 1
#define HAVE_PTHREAD_H 1
#define _REENTRANT 1
#define _THREAD_SAFE 1
#define HAVE_LIBPTHREAD 1
#define THREAD_IMPL_H "thread_pthread.h"
#define THREAD_IMPL_SRC "thread_pthread.c"
#define HAVE_LIBCRYPT 1
#define HAVE_LIBDL 1
#define HAVE_DIRENT_H 1
#define HAVE__BOOL 1
#define HAVE_STDBOOL_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_GRP_H 1
#define HAVE_FCNTL_H 1
#define HAVE_FLOAT_H 1
#define HAVE_LANGINFO_H 1
#define HAVE_LIMITS_H 1
#define HAVE_LOCALE_H 1
#define HAVE_MALLOC_H 1
#define HAVE_PWD_H 1
#define HAVE_SANITIZER_ASAN_INTERFACE_H 1
#define HAVE_STDALIGN_H 1
#define HAVE_STDIO_H 1
#define HAVE_SYS_EVENTFD_H 1
#define HAVE_SYS_FCNTL_H 1
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_PRCTL_H 1
#define HAVE_SYS_RANDOM_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_SENDFILE_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_SYSCALL_H 1
#define HAVE_SYS_SYSMACROS_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_UIO_H 1
#define HAVE_SYSCALL_H 1
#define HAVE_TIME_H 1
#define HAVE_UCONTEXT_H 1
#define HAVE_UTIME_H 1
#define HAVE_STDATOMIC_H 1
#define HAVE_X86INTRIN_H 1
#define HAVE_X86INTRIN_H 1
#define HAVE_GMP_H 1
#define HAVE_LIBGMP 1
#define HAVE_TYPEOF 1
#define restrict __restrict
#define HAVE_LONG_LONG 1
#define HAVE_OFF_T 1
#define SIZEOF_INT 4
#define SIZEOF_SHORT 2
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF___INT64 0
#define SIZEOF___INT128 16
#define SIZEOF_OFF_T 8
#define SIZEOF_VOIDP 8
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8
#define SIZEOF_TIME_T 8
#define SIZEOF_CLOCK_T 8
#define PACKED_STRUCT(x) x __attribute__((packed))
#define USE_UNALIGNED_MEMBER_ACCESS 1
#define PRI_LL_PREFIX "ll"
#define HAVE_PID_T 1
#define rb_pid_t pid_t
#define SIGNEDNESS_OF_PID_T -1
#define PIDT2NUM(v) INT2NUM(v)
#define NUM2PIDT(v) NUM2INT(v)
#define PRI_PIDT_PREFIX PRI_INT_PREFIX
#define HAVE_UID_T 1
#define rb_uid_t uid_t
#define SIGNEDNESS_OF_UID_T +1
#define UIDT2NUM(v) UINT2NUM(v)
#define NUM2UIDT(v) NUM2UINT(v)
#define PRI_UIDT_PREFIX PRI_INT_PREFIX
#define HAVE_GID_T 1
#define rb_gid_t gid_t
#define SIGNEDNESS_OF_GID_T +1
#define GIDT2NUM(v) UINT2NUM(v)
#define NUM2GIDT(v) NUM2UINT(v)
#define PRI_GIDT_PREFIX PRI_INT_PREFIX
#define HAVE_TIME_T 1
#define rb_time_t time_t
#define SIGNEDNESS_OF_TIME_T -1
#define TIMET2NUM(v) LONG2NUM(v)
#define NUM2TIMET(v) NUM2LONG(v)
#define PRI_TIMET_PREFIX PRI_LONG_PREFIX
#define HAVE_DEV_T 1
#define rb_dev_t dev_t
#define SIGNEDNESS_OF_DEV_T +1
#define DEVT2NUM(v) ULONG2NUM(v)
#define NUM2DEVT(v) NUM2ULONG(v)
#define PRI_DEVT_PREFIX PRI_LONG_PREFIX
#define HAVE_MODE_T 1
#define rb_mode_t mode_t
#define SIGNEDNESS_OF_MODE_T +1
#define MODET2NUM(v) UINT2NUM(v)
#define NUM2MODET(v) NUM2UINT(v)
#define PRI_MODET_PREFIX PRI_INT_PREFIX
#define HAVE_RLIM_T 1
#define rb_rlim_t rlim_t
#define SIGNEDNESS_OF_RLIM_T +1
#define RLIM2NUM(v) ULONG2NUM(v)
#define NUM2RLIM(v) NUM2ULONG(v)
#define PRI_RLIM_PREFIX PRI_LONG_PREFIX
#define HAVE_OFF_T 1
#define rb_off_t off_t
#define SIGNEDNESS_OF_OFF_T -1
#define OFFT2NUM(v) LONG2NUM(v)
#define NUM2OFFT(v) NUM2LONG(v)
#define PRI_OFFT_PREFIX PRI_LONG_PREFIX
#define HAVE_CLOCKID_T 1
#define rb_clockid_t clockid_t
#define SIGNEDNESS_OF_CLOCKID_T -1
#define CLOCKID2NUM(v) INT2NUM(v)
#define NUM2CLOCKID(v) NUM2INT(v)
#define PRI_CLOCKID_PREFIX PRI_INT_PREFIX
#define HAVE_VA_ARGS_MACRO 1
#define HAVE__ALIGNOF 1
#define CONSTFUNC(x) __attribute__ ((__const__)) x
#define PUREFUNC(x) __attribute__ ((__pure__)) x
#define NORETURN(x) __attribute__ ((__noreturn__)) x
#define DEPRECATED(x) __attribute__ ((__deprecated__)) x
#define DEPRECATED_BY(n,x) __attribute__ ((__deprecated__("by "#n))) x
#define NOINLINE(x) __attribute__ ((__noinline__)) x
#define NO_SANITIZE(san,x) __attribute__ ((__no_sanitize__(san))) x
#define NO_SANITIZE_ADDRESS(x) __attribute__ ((__no_sanitize_address__)) x
#define NO_ADDRESS_SAFETY_ANALYSIS(x) __attribute__ ((__no_address_safety_analysis__)) x
#define WARN_UNUSED_RESULT(x) __attribute__ ((__warn_unused_result__)) x
#define MAYBE_UNUSED(x) __attribute__ ((__unused__)) x
#define ERRORFUNC(mesg,x) __attribute__ ((__error__ mesg)) x
#define WARNINGFUNC(mesg,x) __attribute__ ((__warning__ mesg)) x
#define WEAK(x) __attribute__ ((__weak__)) x
#define HAVE_FUNC_WEAK 1
#define RUBY_CXX_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
#define HAVE_NULLPTR 1
#define FUNC_UNOPTIMIZED(x) __attribute__ ((__optimize__("O0"))) x
#define FUNC_MINIMIZED(x) __attribute__ ((__optimize__("-Os","-fomit-frame-pointer"))) x
#define HAVE_ATTRIBUTE_FUNCTION_ALIAS 1
#define RUBY_ALIAS_FUNCTION_TYPE(type,prot,name,args) type prot __attribute__((alias(#name)));
#define RUBY_ALIAS_FUNCTION_VOID(prot,name,args) RUBY_ALIAS_FUNCTION_TYPE(void, prot, name, args)
#define HAVE_GCC_ATOMIC_BUILTINS 1
#define HAVE_GCC_SYNC_BUILTINS 1
#define HAVE___BUILTIN_UNREACHABLE 1
#define RUBY_FUNC_EXPORTED __attribute__ ((__visibility__("default"))) extern
#define RUBY_FUNC_NONNULL(n,x) __attribute__ ((__nonnull__(n))) x
#define RUBY_FUNCTION_NAME_STRING __func__
#define ENUM_OVER_INT 1
#define HAVE_DECL_SYS_NERR 1
#define HAVE_DECL_GETENV 1
#define SIZEOF_SIZE_T 8
#define SIZEOF_PTRDIFF_T 8
#define SIZEOF_DEV_T 8
#define PRI_SIZE_PREFIX "z"
#define PRI_PTRDIFF_PREFIX "t"
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
#define HAVE_STRUCT_STAT_ST_RDEV 1
#define SIZEOF_STRUCT_STAT_ST_SIZE SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_BLOCKS SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_INO SIZEOF_LONG
#define SIZEOF_STRUCT_STAT_ST_DEV SIZEOF_DEV_T
#define SIZEOF_STRUCT_STAT_ST_RDEV SIZEOF_DEV_T
#define HAVE_STRUCT_STAT_ST_ATIM 1
#define HAVE_STRUCT_STAT_ST_MTIM 1
#define HAVE_STRUCT_STAT_ST_CTIM 1
#define HAVE_STRUCT_STATX_STX_BTIME 1
#define HAVE_STRUCT_TIMEVAL 1
#define SIZEOF_STRUCT_TIMEVAL_TV_SEC SIZEOF_TIME_T
#define HAVE_STRUCT_TIMESPEC 1
#define HAVE_STRUCT_TIMEZONE 1
#define HAVE_RB_FD_INIT 1
#define HAVE_INT8_T 1
#define SIZEOF_INT8_T 1
#define HAVE_UINT8_T 1
#define SIZEOF_UINT8_T 1
#define HAVE_INT16_T 1
#define SIZEOF_INT16_T 2
#define HAVE_UINT16_T 1
#define SIZEOF_UINT16_T 2
#define HAVE_INT32_T 1
#define SIZEOF_INT32_T 4
#define HAVE_UINT32_T 1
#define SIZEOF_UINT32_T 4
#define HAVE_INT64_T 1
#define SIZEOF_INT64_T 8
#define HAVE_UINT64_T 1
#define SIZEOF_UINT64_T 8
#define HAVE_INT128_T 1
#define int128_t __int128
#define SIZEOF_INT128_T SIZEOF___INT128
#define HAVE_UINT128_T 1
#define uint128_t unsigned __int128
#define SIZEOF_UINT128_T SIZEOF___INT128
#define HAVE_INTPTR_T 1
#define SIZEOF_INTPTR_T 8
#define HAVE_UINTPTR_T 1
#define SIZEOF_UINTPTR_T 8
#define HAVE_SSIZE_T 1
#define SIZEOF_SSIZE_T 8
#define STACK_END_ADDRESS __libc_stack_end
#define GETGROUPS_T gid_t
#define HAVE_ALLOCA_H 1
#define HAVE_ALLOCA 1
#define HAVE_DUP 1
#define HAVE_DUP2 1
#define HAVE_ACOSH 1
#define HAVE_CBRT 1
#define HAVE_CRYPT 1
#define HAVE_ERF 1
#define HAVE_EXPLICIT_BZERO 1
#define HAVE_FFS 1
#define HAVE_FLOCK 1
#define HAVE_HYPOT 1
#define HAVE_LGAMMA_R 1
#define HAVE_MEMMOVE 1
#define HAVE_NAN 1
#define HAVE_NEXTAFTER 1
#define HAVE_STRCHR 1
#define HAVE_STRERROR 1
#define HAVE_STRSTR 1
#define HAVE_TGAMMA 1
#define HAVE_ISFINITE 1
#define SPT_TYPE SPT_REUSEARGV
#define HAVE_SIGNBIT 1
#define HAVE_FORK 1
#define HAVE_VFORK 1
#define HAVE_WORKING_VFORK 1
#define HAVE_WORKING_FORK 1
#define HAVE__LONGJMP 1
#define HAVE_ATAN2L 1
#define HAVE_ATAN2F 1
#define HAVE_DECL_ATOMIC_SIGNAL_FENCE 1
#define HAVE_CHMOD 1
#define HAVE_CHOWN 1
#define HAVE_CHROOT 1
#define HAVE_CLOCK_GETTIME 1
#define HAVE_COPY_FILE_RANGE 1
#define HAVE_COSH 1
#define HAVE_CRYPT_R 1
#define HAVE_DIRFD 1
#define HAVE_DL_ITERATE_PHDR 1
#define HAVE_DLOPEN 1
#define HAVE_DLADDR 1
#define HAVE_DUP3 1
#define HAVE_EACCESS 1
#define HAVE_ENDGRENT 1
#define HAVE_EVENTFD 1
#define HAVE_EXECL 1
#define HAVE_EXECLE 1
#define HAVE_EXECV 1
#define HAVE_EXECVE 1
#define HAVE_FCHMOD 1
#define HAVE_FCHOWN 1
#define HAVE_FCNTL 1
#define HAVE_FDATASYNC 1
#define HAVE_FDOPENDIR 1
#define HAVE_FMOD 1
#define HAVE_FSTATAT 1
#define HAVE_FSYNC 1
#define HAVE_FTRUNCATE 1
#define HAVE_FTRUNCATE64 1
#define HAVE_GETCWD 1
#define HAVE_GETEGID 1
#define HAVE_GETENTROPY 1
#define HAVE_GETEUID 1
#define HAVE_GETGID 1
#define HAVE_GETGRNAM 1
#define HAVE_GETGRNAM_R 1
#define HAVE_GETGROUPS 1
#define HAVE_GETLOGIN 1
#define HAVE_GETLOGIN_R 1
#define HAVE_GETPGID 1
#define HAVE_GETPGRP 1
#define HAVE_GETPPID 1
#define HAVE_GETPRIORITY 1
#define HAVE_GETPWNAM 1
#define HAVE_GETPWNAM_R 1
#define HAVE_GETPWUID 1
#define HAVE_GETPWUID_R 1
#define HAVE_GETRANDOM 1
#define HAVE_GETRESGID 1
#define HAVE_GETRESUID 1
#define HAVE_GETRLIMIT 1
#define HAVE_GETSID 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_GETUID 1
#define HAVE_GMTIME_R 1
#define HAVE_GRANTPT 1
#define HAVE_INITGROUPS 1
#define HAVE_IOCTL 1
#define HAVE_KILL 1
#define HAVE_KILLPG 1
#define HAVE_LCHOWN 1
#define HAVE_LINK 1
#define HAVE_LLABS 1
#define HAVE_LOCKF 1
#define HAVE_LOG2 1
#define HAVE_LSTAT 1
#define HAVE_LUTIMES 1
#define HAVE_MALLOC_USABLE_SIZE 1
#define HAVE_MBLEN 1
#define HAVE_MEMALIGN 1
#define HAVE_WRITEV 1
#define HAVE_MEMRCHR 1
#define HAVE_MEMMEM 1
#define HAVE_MKFIFO 1
#define HAVE_MKNOD 1
#define HAVE_MKTIME 1
#define HAVE_MMAP 1
#define HAVE_MREMAP 1
#define HAVE_OPENAT 1
#define HAVE_PCLOSE 1
#define HAVE_PIPE 1
#define HAVE_PIPE2 1
#define HAVE_POLL 1
#define HAVE_POPEN 1
#define HAVE_POSIX_FADVISE 1
#define HAVE_POSIX_MADVISE 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_PPOLL 1
#define HAVE_PREAD 1
#define HAVE_PWRITE 1
#define HAVE_QSORT_R 1
#define HAVE_READLINK 1
#define HAVE_REALPATH 1
#define HAVE_ROUND 1
#define HAVE_SCHED_GETAFFINITY 1
#define HAVE_SEEKDIR 1
#define HAVE_SENDFILE 1
#define HAVE_SETEGID 1
#define HAVE_SETENV 1
#define HAVE_SETEUID 1
#define HAVE_SETGID 1
#define HAVE_SETGROUPS 1
#define HAVE_SETPGID 1
#define HAVE_SETPGRP 1
#define HAVE_SETREGID 1
#define HAVE_SETRESGID 1
#define HAVE_SETRESUID 1
#define HAVE_SETREUID 1
#define HAVE_SETRLIMIT 1
#define HAVE_SETSID 1
#define HAVE_SETUID 1
#define HAVE_SHUTDOWN 1
#define HAVE_SIGACTION 1
#define HAVE_SIGALTSTACK 1
#define HAVE_SIGPROCMASK 1
#define HAVE_SINH 1
#define HAVE_SYMLINK 1
#define HAVE_SYSCALL 1
#define HAVE_SYSCONF 1
#define HAVE_SYSTEM 1
#define HAVE_TANH 1
#define HAVE_TELLDIR 1
#define HAVE_TIMEGM 1
#define HAVE_TIMES 1
#define HAVE_TRUNCATE 1
#define HAVE_TRUNCATE64 1
#define HAVE_TZSET 1
#define HAVE_UMASK 1
#define HAVE_UNSETENV 1
#define HAVE_UTIMENSAT 1
#define HAVE_UTIMES 1
#define HAVE_WAIT4 1
#define HAVE_WAITPID 1
#define HAVE_STATX 1
#define HAVE_CRYPT_H 1
#define HAVE_STRUCT_CRYPT_DATA_INITIALIZED 1
#define HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN 1
#define HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED 1
#define HAVE_BUILTIN___BUILTIN_BSWAP16 1
#define HAVE_BUILTIN___BUILTIN_BSWAP32 1
#define HAVE_BUILTIN___BUILTIN_BSWAP64 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNT 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNTLL 1
#define HAVE_BUILTIN___BUILTIN_CLZ 1
#define HAVE_BUILTIN___BUILTIN_CLZL 1
#define HAVE_BUILTIN___BUILTIN_CLZLL 1
#define HAVE_BUILTIN___BUILTIN_CTZ 1
#define HAVE_BUILTIN___BUILTIN_CTZLL 1
#define HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P 1
#define HAVE_BUILTIN___BUILTIN_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P 1
#define HAVE_BUILTIN___BUILTIN_TRAP 1
#define HAVE_BUILTIN___BUILTIN_EXPECT 1
#define HAVE_GNU_QSORT_R 1
#define ATAN2_INF_C99 1
#define HAVE_CLOCK_GETRES 1
#define HAVE_LIBRT 1
#define HAVE_LIBRT 1
#define HAVE_TIMER_CREATE 1
#define HAVE_TIMER_SETTIME 1
#define HAVE_STRUCT_TM_TM_ZONE 1
#define HAVE_TM_ZONE 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_DAYLIGHT 1
#define NEGATIVE_TIME_T 1
#define POSIX_SIGNAL 1
#define HAVE_SIG_T 1
#define RSHIFT(x,y) ((x)>>(int)(y))
#define USE_COPY_FILE_RANGE 1
#define HAVE__SC_CLK_TCK 1
#define STACK_GROW_DIRECTION -1
#define COROUTINE_H "coroutine/amd64/Context.h"
#define HAVE_SCHED_YIELD 1
#define HAVE_PTHREAD_ATTR_SETINHERITSCHED 1
#define HAVE_PTHREAD_ATTR_GETSTACK 1
#define HAVE_PTHREAD_ATTR_GETGUARDSIZE 1
#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
#define HAVE_PTHREAD_SETNAME_NP 1
#define HAVE_PTHREAD_SIGMASK 1
#define HAVE_PTHREAD_GETATTR_NP 1
#define SET_CURRENT_THREAD_NAME(name) pthread_setname_np(pthread_self(), name)
#define SET_ANOTHER_THREAD_NAME(thid,name) pthread_setname_np(thid, name)
#define DEFINE_MCONTEXT_PTR(mc,uc) mcontext_t *mc = &(uc)->uc_mcontext
#define HAVE_GETCONTEXT 1
#define HAVE_SETCONTEXT 1
#define HAVE_SYS_USER_H 1
#define HAVE_CONST_PAGE_SIZE 1
#define IOCTL_REQ_TYPE unsigned long
#define NUM2IOCTLREQ(num) NUM2ULONG(num)
#define USE_ELF 1
#define HAVE_ELF_H 1
#define HAVE_LIBZ 1
#define HAVE_BACKTRACE 1
#define DLEXT_MAXLEN 3
#define DLEXT ".so"
#define ENABLE_MULTIARCH 1
#define LIBDIR_BASENAME "lib64"
#define HAVE__SETJMP 1
#define RUBY_SETJMP(env) _setjmp((env))
#define RUBY_LONGJMP(env,val) _longjmp((env),val)
#define RUBY_JMP_BUF jmp_buf
#define USE_MJIT 1
#define USE_YJIT 0
#define RUBY_LIB_VERSION_BLANK 1
#define RUBY_PLATFORM "x86_64-linux"
#define RBIMPL_COMPILER_SINCE_H
#define RBIMPL_COMPILER_IS_H
#define RBIMPL_COMPILER_IS(cc) RBIMPL_COMPILER_IS_ ## cc
#define RBIMPL_COMPILER_IS_APPLE_H
#define RBIMPL_COMPILER_IS_Apple 0
#define RBIMPL_COMPILER_IS_CLANG_H
#define RBIMPL_COMPILER_IS_Clang 0
#define RBIMPL_COMPILER_IS_GCC_H
#define RBIMPL_COMPILER_IS_INTEL_H
#define RBIMPL_COMPILER_IS_Intel 0
#define RBIMPL_COMPILER_IS_GCC 1
#define RBIMPL_COMPILER_VERSION_MAJOR __GNUC__
#define RBIMPL_COMPILER_VERSION_MINOR __GNUC_MINOR__
#define RBIMPL_COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
#define RBIMPL_COMPILER_IS_MSVC_H
#define RBIMPL_COMPILER_IS_MSVC 0
#define RBIMPL_COMPILER_IS_SUNPRO_H
#define RBIMPL_COMPILER_IS_SunPro 0
#define RBIMPL_COMPILER_SINCE(cc,x,y,z) (RBIMPL_COMPILER_IS(cc) && ((RBIMPL_COMPILER_VERSION_MAJOR > (x)) || ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && ((RBIMPL_COMPILER_VERSION_MINOR > (y)) || ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && (RBIMPL_COMPILER_VERSION_PATCH >= (z)))))))
#define RBIMPL_COMPILER_BEFORE(cc,x,y,z) (RBIMPL_COMPILER_IS(cc) && ((RBIMPL_COMPILER_VERSION_MAJOR < (x)) || ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && ((RBIMPL_COMPILER_VERSION_MINOR < (y)) || ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && (RBIMPL_COMPILER_VERSION_PATCH < (z)))))))
#undef HAVE_PROTOTYPES
#define HAVE_PROTOTYPES 1
#undef HAVE_STDARG_PROTOTYPES
#define HAVE_STDARG_PROTOTYPES 1
#undef TOKEN_PASTE
#define TOKEN_PASTE(x,y) x ##y
#define STRINGIZE(expr) STRINGIZE0(expr)
#define STRINGIZE0(expr) #expr
#define UNALIGNED_WORD_ACCESS 1
#define RBIMPL_TEST3(q,w,e,...) e
#define RBIMPL_TEST2(...) RBIMPL_TEST3(__VA_OPT__(,),1,0,0)
#define RBIMPL_TEST1() RBIMPL_TEST2("ruby")
#define HAVE___VA_OPT__
#undef RBIMPL_TEST1
#undef RBIMPL_TEST2
#undef RBIMPL_TEST3
#define USE_RVARGC 1
#define _STDARG_H
#define _ANSI_STDARG_H_
#undef __need___va_list
#define __GNUC_VA_LIST
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define va_copy(d,s) __builtin_va_copy(d,s)
#define __va_copy(d,s) __builtin_va_copy(d,s)
#define _VA_LIST_
#define _VA_LIST
#define _VA_LIST_DEFINED
#define _VA_LIST_T_H
#define __va_list__
#define RUBY_DEFINES_H 1
#define _STDIO_H 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#define _FEATURES_H 1
#undef __USE_ISOC11
#undef __USE_ISOC99
#undef __USE_ISOC95
#undef __USE_ISOCXX11
#undef __USE_POSIX
#undef __USE_POSIX2
#undef __USE_POSIX199309
#undef __USE_POSIX199506
#undef __USE_XOPEN
#undef __USE_XOPEN_EXTENDED
#undef __USE_UNIX98
#undef __USE_XOPEN2K
#undef __USE_XOPEN2KXSI
#undef __USE_XOPEN2K8
#undef __USE_XOPEN2K8XSI
#undef __USE_LARGEFILE
#undef __USE_LARGEFILE64
#undef __USE_FILE_OFFSET64
#undef __USE_MISC
#undef __USE_ATFILE
#undef __USE_GNU
#undef __USE_FORTIFY_LEVEL
#undef __KERNEL_STRICT_NAMES
#undef __GLIBC_USE_DEPRECATED_GETS
#define __KERNEL_STRICT_NAMES
#define __GNUC_PREREQ(maj,min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#define __glibc_clang_prereq(maj,min) 0
#define __GLIBC_USE(F) __GLIBC_USE_ ## F
#undef _ISOC95_SOURCE
#define _ISOC95_SOURCE 1
#undef _ISOC99_SOURCE
#define _ISOC99_SOURCE 1
#undef _ISOC11_SOURCE
#define _ISOC11_SOURCE 1
#undef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#undef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED 1
#undef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE 1
#undef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#undef _ATFILE_SOURCE
#define _ATFILE_SOURCE 1
#undef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#define __USE_ISOC11 1
#define __USE_ISOC99 1
#define __USE_ISOC95 1
#undef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#define __USE_POSIX 1
#define __USE_POSIX2 1
#define __USE_POSIX199309 1
#define __USE_POSIX199506 1
#define __USE_XOPEN2K 1
#undef __USE_ISOC95
#define __USE_ISOC95 1
#undef __USE_ISOC99
#define __USE_ISOC99 1
#define __USE_XOPEN2K8 1
#undef _ATFILE_SOURCE
#define _ATFILE_SOURCE 1
#define __USE_XOPEN 1
#define __USE_XOPEN_EXTENDED 1
#define __USE_UNIX98 1
#undef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE 1
#define __USE_XOPEN2K8 1
#define __USE_XOPEN2K8XSI 1
#define __USE_XOPEN2K 1
#define __USE_XOPEN2KXSI 1
#undef __USE_ISOC95
#define __USE_ISOC95 1
#undef __USE_ISOC99
#define __USE_ISOC99 1
#define __USE_LARGEFILE 1
#define __USE_LARGEFILE64 1
#define __USE_MISC 1
#define __USE_ATFILE 1
#define __USE_GNU 1
#define __USE_FORTIFY_LEVEL 2
#define __GLIBC_USE_DEPRECATED_GETS 0
#undef __GNU_LIBRARY__
#define __GNU_LIBRARY__ 6
#define __GLIBC__ 2
#define __GLIBC_MINOR__ 28
#define __GLIBC_PREREQ(maj,min) ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
#define _SYS_CDEFS_H 1
#undef __P
#undef __PMT
#define __LEAF , __leaf__
#define __LEAF_ATTR __attribute__ ((__leaf__))
#define __THROW __attribute__ ((__nothrow__ __LEAF))
#define __THROWNL __attribute__ ((__nothrow__))
#define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
#define __NTHNL(fct) __attribute__ ((__nothrow__)) fct
#define __glibc_clang_has_extension(ext) 0
#define __P(args) args
#define __PMT(args) args
#define __CONCAT(x,y) x ## y
#define __STRING(x) #x
#define __ptr_t void *
#define __BEGIN_DECLS
#define __END_DECLS
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
#define __bos0(ptr) __builtin_object_size (ptr, 0)
#define __glibc_objsize0(__o) __bos0 (__o)
#define __glibc_objsize(__o) __bos (__o)
#define __glibc_safe_len_cond(__l,__s,__osz) ((__l) <= (__osz) / (__s))
#define __glibc_unsigned_or_positive(__l) ((__typeof (__l)) 0 < (__typeof (__l)) -1 || (__builtin_constant_p (__l) && (__l) > 0))
#define __glibc_safe_or_unknown_len(__l,__s,__osz) ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) || (__glibc_unsigned_or_positive (__l) && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))) && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
#define __glibc_unsafe_len(__l,__s,__osz) (__glibc_unsigned_or_positive (__l) && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
#define __glibc_fortify(f,__l,__s,__osz,...) (__glibc_safe_or_unknown_len (__l, __s, __osz) ? __ ## f ## _alias (__VA_ARGS__) : (__glibc_unsafe_len (__l, __s, __osz) ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) : __ ## f ## _chk (__VA_ARGS__, __osz)))
#define __glibc_fortify_n(f,__l,__s,__osz,...) (__glibc_safe_or_unknown_len (__l, __s, __osz) ? __ ## f ## _alias (__VA_ARGS__) : (__glibc_unsafe_len (__l, __s, __osz) ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
#define __warndecl(name,msg) extern void name (void) __attribute__((__warning__ (msg)))
#define __warnattr(msg) __attribute__((__warning__ (msg)))
#define __errordecl(name,msg) extern void name (void) __attribute__((__error__ (msg)))
#define __flexarr []
#define __glibc_c99_flexarr_available 1
#define __REDIRECT(name,proto,alias) name proto __asm__ (__ASMNAME (#alias))
#define __REDIRECT_NTH(name,proto,alias) name proto __asm__ (__ASMNAME (#alias)) __THROW
#define __REDIRECT_NTHNL(name,proto,alias) name proto __asm__ (__ASMNAME (#alias)) __THROWNL
#define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
#define __ASMNAME2(prefix,cname) __STRING (prefix) cname
#define __attribute_malloc__ __attribute__ ((__malloc__))
#define __attribute_alloc_size__(params) __attribute__ ((__alloc_size__ params))
#define __attribute_pure__ __attribute__ ((__pure__))
#define __attribute_const__ __attribute__ ((__const__))
#define __attribute_used__ __attribute__ ((__used__))
#define __attribute_noinline__ __attribute__ ((__noinline__))
#define __attribute_deprecated__ __attribute__ ((__deprecated__))
#define __attribute_deprecated_msg__(msg) __attribute__ ((__deprecated__ (msg)))
#define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
#define __attribute_format_strfmon__(a,b) __attribute__ ((__format__ (__strfmon__, a, b)))
#define __nonnull(params) __attribute__ ((__nonnull__ params))
#define __attribute_warn_unused_result__ __attribute__ ((__warn_unused_result__))
#define __wur __attribute_warn_unused_result__
#undef __always_inline
#define __always_inline __inline __attribute__ ((__always_inline__))
#define __attribute_artificial__ __attribute__ ((__artificial__))
#define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
#define __extern_always_inline extern __always_inline __attribute__ ((__gnu_inline__))
#define __fortify_function __extern_always_inline __attribute_artificial__
#define __va_arg_pack() __builtin_va_arg_pack ()
#define __va_arg_pack_len() __builtin_va_arg_pack_len ()
#define __restrict_arr __restrict
#define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
#define __glibc_likely(cond) __builtin_expect ((cond), 1)
#define __glibc_has_attribute(attr) __has_attribute (attr)
#define __attribute_nonstring__ __attribute__ ((__nonstring__))
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define __LDBL_REDIR1(name,proto,alias) name proto
#define __LDBL_REDIR(name,proto) name proto
#define __LDBL_REDIR1_NTH(name,proto,alias) name proto __THROW
#define __LDBL_REDIR_NTH(name,proto) name proto __THROW
#define __LDBL_REDIR_DECL(name)
#define __REDIRECT_LDBL(name,proto,alias) __REDIRECT (name, proto, alias)
#define __REDIRECT_NTH_LDBL(name,proto,alias) __REDIRECT_NTH (name, proto, alias)
#define __glibc_macro_warning1(message) _Pragma (#message)
#define __glibc_macro_warning(message) __glibc_macro_warning1 (GCC warning message)
#define __HAVE_GENERIC_SELECTION 1
#define __USE_EXTERN_INLINES 1
#define __stub___compat_bdflush
#define __stub_chflags
#define __stub_fattach
#define __stub_fchflags
#define __stub_fdetach
#define __stub_getmsg
#define __stub_gtty
#define __stub_lchmod
#define __stub_putmsg
#define __stub_revoke
#define __stub_setlogin
#define __stub_sigreturn
#define __stub_sstk
#define __stub_stty
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define __need_size_t
#define __need_NULL
#define __size_t__
#define __SIZE_T__
#define _SIZE_T
#define _SYS_SIZE_T_H
#define _T_SIZE_
#define _T_SIZE
#define __SIZE_T
#define _SIZE_T_
#define _BSD_SIZE_T_
#define _SIZE_T_DEFINED_
#define _SIZE_T_DEFINED
#define _BSD_SIZE_T_DEFINED_
#define _SIZE_T_DECLARED
#define ___int_size_t_h
#define _GCC_SIZE_T
#define _SIZET_
#define __size_t
#undef __need_size_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define __need___va_list
#define _BITS_TYPES_H 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define __S16_TYPE short int
#define __U16_TYPE unsigned short int
#define __S32_TYPE int
#define __U32_TYPE unsigned int
#define __SLONGWORD_TYPE long int
#define __ULONGWORD_TYPE unsigned long int
#define __SQUAD_TYPE long int
#define __UQUAD_TYPE unsigned long int
#define __SWORD_TYPE long int
#define __UWORD_TYPE unsigned long int
#define __SLONG32_TYPE int
#define __ULONG32_TYPE unsigned int
#define __S64_TYPE long int
#define __U64_TYPE unsigned long int
#define __STD_TYPE typedef
#define _BITS_TYPESIZES_H 1
#define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
#define __SYSCALL_ULONG_TYPE __ULONGWORD_TYPE
#define __DEV_T_TYPE __UQUAD_TYPE
#define __UID_T_TYPE __U32_TYPE
#define __GID_T_TYPE __U32_TYPE
#define __INO_T_TYPE __SYSCALL_ULONG_TYPE
#define __INO64_T_TYPE __UQUAD_TYPE
#define __MODE_T_TYPE __U32_TYPE
#define __NLINK_T_TYPE __SYSCALL_ULONG_TYPE
#define __FSWORD_T_TYPE __SYSCALL_SLONG_TYPE
#define __OFF_T_TYPE __SYSCALL_SLONG_TYPE
#define __OFF64_T_TYPE __SQUAD_TYPE
#define __PID_T_TYPE __S32_TYPE
#define __RLIM_T_TYPE __SYSCALL_ULONG_TYPE
#define __RLIM64_T_TYPE __UQUAD_TYPE
#define __BLKCNT_T_TYPE __SYSCALL_SLONG_TYPE
#define __BLKCNT64_T_TYPE __SQUAD_TYPE
#define __FSBLKCNT_T_TYPE __SYSCALL_ULONG_TYPE
#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
#define __FSFILCNT_T_TYPE __SYSCALL_ULONG_TYPE
#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SYSCALL_SLONG_TYPE
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SYSCALL_SLONG_TYPE
#define __DADDR_T_TYPE __S32_TYPE
#define __KEY_T_TYPE __S32_TYPE
#define __CLOCKID_T_TYPE __S32_TYPE
#define __TIMER_T_TYPE void *
#define __BLKSIZE_T_TYPE __SYSCALL_SLONG_TYPE
#define __FSID_T_TYPE struct { int __val[2]; }
#define __SSIZE_T_TYPE __SWORD_TYPE
#define __CPU_MASK_TYPE __SYSCALL_ULONG_TYPE
#define __OFF_T_MATCHES_OFF64_T 1
#define __INO_T_MATCHES_INO64_T 1
#define __RLIM_T_MATCHES_RLIM64_T 1
#define __FD_SETSIZE 1024
#undef __STD_TYPE
#define _____fpos_t_defined 1
#define ____mbstate_t_defined 1
#define _____fpos64_t_defined 1
#define ____FILE_defined 1
#define __FILE_defined 1
#define __struct_FILE_defined 1
#define __getc_unlocked_body(_fp) (__glibc_unlikely ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end) ? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++)
#define __putc_unlocked_body(_ch,_fp) (__glibc_unlikely ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) ? __overflow (_fp, (unsigned char) (_ch)) : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))
#define _IO_EOF_SEEN 0x0010
#define __feof_unlocked_body(_fp) (((_fp)->_flags & _IO_EOF_SEEN) != 0)
#define _IO_ERR_SEEN 0x0020
#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)
#define _IO_USER_LOCK 0x8000
#define __cookie_io_functions_t_defined 1
#define __off_t_defined
#define __off64_t_defined
#define __ssize_t_defined
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
#define BUFSIZ 8192
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_DATA 3
#define SEEK_HOLE 4
#define P_tmpdir "/tmp"
#define _BITS_STDIO_LIM_H 1
#define L_tmpnam 20
#define TMP_MAX 238328
#define FILENAME_MAX 4096
#define L_ctermid 9
#define L_cuserid 9
#undef FOPEN_MAX
#define FOPEN_MAX 16
#define stdin stdin
#define stdout stdout
#define stderr stderr
#define RENAME_NOREPLACE (1 << 0)
#define RENAME_EXCHANGE (1 << 1)
#define RENAME_WHITEOUT (1 << 2)
#define _BITS_STDIO_H 1
#define __STDIO_INLINE __extern_inline
#define fread_unlocked(ptr,size,n,stream) (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) && (size_t) (size) * (size_t) (n) <= 8 && (size_t) (size) != 0) ? ({ char *__ptr = (char *) (ptr); FILE *__stream = (stream); size_t __cnt; for (__cnt = (size_t) (size) * (size_t) (n); __cnt > 0; --__cnt) { int __c = getc_unlocked (__stream); if (__c == EOF) break; *__ptr++ = __c; } ((size_t) (size) * (size_t) (n) - __cnt) / (size_t) (size); }) : (((__builtin_constant_p (size) && (size_t) (size) == 0) || (__builtin_constant_p (n) && (size_t) (n) == 0)) ? ((void) (ptr), (void) (stream), (void) (size), (void) (n), (size_t) 0) : fread_unlocked (ptr, size, n, stream))))
#define fwrite_unlocked(ptr,size,n,stream) (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) && (size_t) (size) * (size_t) (n) <= 8 && (size_t) (size) != 0) ? ({ const char *__ptr = (const char *) (ptr); FILE *__stream = (stream); size_t __cnt; for (__cnt = (size_t) (size) * (size_t) (n); __cnt > 0; --__cnt) if (putc_unlocked (*__ptr++, __stream) == EOF) break; ((size_t) (size) * (size_t) (n) - __cnt) / (size_t) (size); }) : (((__builtin_constant_p (size) && (size_t) (size) == 0) || (__builtin_constant_p (n) && (size_t) (n) == 0)) ? ((void) (ptr), (void) (stream), (void) (size), (void) (n), (size_t) 0) : fwrite_unlocked (ptr, size, n, stream))))
#undef __STDIO_INLINE
#define _BITS_STDIO2_H 1
#undef fread_unlocked
#define _SYS_TYPES_H 1
#define __u_char_defined
#define __ino_t_defined
#define __ino64_t_defined
#define __dev_t_defined
#define __gid_t_defined
#define __mode_t_defined
#define __nlink_t_defined
#define __uid_t_defined
#define __pid_t_defined
#define __id_t_defined
#define __daddr_t_defined
#define __key_t_defined
#define __clock_t_defined 1
#define __clockid_t_defined 1
#define __time_t_defined 1
#define __timer_t_defined 1
#define __useconds_t_defined
#define __suseconds_t_defined
#define __need_size_t
#undef __need_size_t
#undef __need_NULL
#define _BITS_STDINT_INTN_H 1
#define __BIT_TYPES_DEFINED__ 1
#define _ENDIAN_H 1
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __PDP_ENDIAN 3412
#define __BYTE_ORDER __LITTLE_ENDIAN
#define __FLOAT_WORD_ORDER __BYTE_ORDER
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#define BIG_ENDIAN __BIG_ENDIAN
#define PDP_ENDIAN __PDP_ENDIAN
#define BYTE_ORDER __BYTE_ORDER
#define __LONG_LONG_PAIR(HI,LO) LO, HI
#define _BITS_BYTESWAP_H 1
#define __bswap_constant_16(x) ((__uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
#define __bswap_constant_32(x) ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
#define __bswap_constant_64(x) ((((x) & 0xff00000000000000ull) >> 56) | (((x) & 0x00ff000000000000ull) >> 40) | (((x) & 0x0000ff0000000000ull) >> 24) | (((x) & 0x000000ff00000000ull) >> 8) | (((x) & 0x00000000ff000000ull) << 8) | (((x) & 0x0000000000ff0000ull) << 24) | (((x) & 0x000000000000ff00ull) << 40) | (((x) & 0x00000000000000ffull) << 56))
#define _BITS_UINTN_IDENTITY_H 1
#define htobe16(x) __bswap_16 (x)
#define htole16(x) __uint16_identity (x)
#define be16toh(x) __bswap_16 (x)
#define le16toh(x) __uint16_identity (x)
#define htobe32(x) __bswap_32 (x)
#define htole32(x) __uint32_identity (x)
#define be32toh(x) __bswap_32 (x)
#define le32toh(x) __uint32_identity (x)
#define htobe64(x) __bswap_64 (x)
#define htole64(x) __uint64_identity (x)
#define be64toh(x) __bswap_64 (x)
#define le64toh(x) __uint64_identity (x)
#define _SYS_SELECT_H 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define __FD_ZERO_STOS "stosq"
#define __FD_ZERO(fdsp) do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&__FDS_BITS (fdsp)[0]) : "memory"); } while (0)
#define __FD_SET(d,set) ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d)))
#define __FD_CLR(d,set) ((void) (__FDS_BITS (set)[__FD_ELT (d)] &= ~__FD_MASK (d)))
#define __FD_ISSET(d,set) ((__FDS_BITS (set)[__FD_ELT (d)] & __FD_MASK (d)) != 0)
#define __sigset_t_defined 1
#define ____sigset_t_defined
#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
#define __timeval_defined 1
#define _STRUCT_TIMESPEC 1
#undef __NFDBITS
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
#define __FD_ELT(d) ((d) / __NFDBITS)
#define __FD_MASK(d) ((__fd_mask) (1UL << ((d) % __NFDBITS)))
#define __FDS_BITS(set) ((set)->fds_bits)
#define FD_SETSIZE __FD_SETSIZE
#define NFDBITS __NFDBITS
#define FD_SET(fd,fdsetp) __FD_SET (fd, fdsetp)
#define FD_CLR(fd,fdsetp) __FD_CLR (fd, fdsetp)
#define FD_ISSET(fd,fdsetp) __FD_ISSET (fd, fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
#undef __FD_ELT
#define __FD_ELT(d) __extension__ ({ long int __d = (d); (__builtin_constant_p (__d) ? (0 <= __d && __d < __FD_SETSIZE ? (__d / __NFDBITS) : __fdelt_warn (__d)) : __fdelt_chk (__d)); })
#define __blksize_t_defined
#define __blkcnt_t_defined
#define __fsblkcnt_t_defined
#define __fsfilcnt_t_defined
#define _BITS_PTHREADTYPES_COMMON_H 1
#define _THREAD_SHARED_TYPES_H 1
#define _BITS_PTHREADTYPES_ARCH_H 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define __SIZEOF_PTHREAD_MUTEX_T 40
#define __SIZEOF_PTHREAD_ATTR_T 56
#define __SIZEOF_PTHREAD_MUTEX_T 40
#define __SIZEOF_PTHREAD_RWLOCK_T 56
#define __SIZEOF_PTHREAD_BARRIER_T 32
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
#define __SIZEOF_PTHREAD_COND_T 48
#define __SIZEOF_PTHREAD_CONDATTR_T 4
#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
#define __PTHREAD_COMPAT_PADDING_MID
#define __PTHREAD_COMPAT_PADDING_END
#define __PTHREAD_MUTEX_LOCK_ELISION 1
#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND 0
#define __PTHREAD_MUTEX_USE_UNION 0
#define __LOCK_ALIGNMENT
#define __ONCE_ALIGNMENT
#define __PTHREAD_RWLOCK_ELISION_EXTRA 0, { 0, 0, 0, 0, 0, 0, 0 }
#define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
#define __PTHREAD_SPINS_DATA short __spins; short __elision
#define __PTHREAD_SPINS 0, 0
#define __PTHREAD_MUTEX_HAVE_PREV 1
#define __have_pthread_attr_t 1
#define _SYS_STAT_H 1
#define _BITS_STAT_H 1
#define _STAT_VER_KERNEL 0
#define _STAT_VER_LINUX 1
#define _MKNOD_VER_LINUX 0
#define _STAT_VER _STAT_VER_LINUX
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
#define _STATBUF_ST_BLKSIZE
#define _STATBUF_ST_RDEV
#define _STATBUF_ST_NSEC
#define __S_IFMT 0170000
#define __S_IFDIR 0040000
#define __S_IFCHR 0020000
#define __S_IFBLK 0060000
#define __S_IFREG 0100000
#define __S_IFIFO 0010000
#define __S_IFLNK 0120000
#define __S_IFSOCK 0140000
#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
#define __S_ISUID 04000
#define __S_ISGID 02000
#define __S_ISVTX 01000
#define __S_IREAD 0400
#define __S_IWRITE 0200
#define __S_IEXEC 0100
#define UTIME_NOW ((1l << 30) - 1l)
#define UTIME_OMIT ((1l << 30) - 2l)
#define S_IFMT __S_IFMT
#define S_IFDIR __S_IFDIR
#define S_IFCHR __S_IFCHR
#define S_IFBLK __S_IFBLK
#define S_IFREG __S_IFREG
#define S_IFIFO __S_IFIFO
#define S_IFLNK __S_IFLNK
#define S_IFSOCK __S_IFSOCK
#define __S_ISTYPE(mode,mask) (((mode) & __S_IFMT) == (mask))
#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
#define S_ISCHR(mode) __S_ISTYPE((mode), __S_IFCHR)
#define S_ISBLK(mode) __S_ISTYPE((mode), __S_IFBLK)
#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
#define S_ISFIFO(mode) __S_ISTYPE((mode), __S_IFIFO)
#define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK)
#define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK)
#define S_TYPEISMQ(buf) __S_TYPEISMQ(buf)
#define S_TYPEISSEM(buf) __S_TYPEISSEM(buf)
#define S_TYPEISSHM(buf) __S_TYPEISSHM(buf)
#define S_ISUID __S_ISUID
#define S_ISGID __S_ISGID
#define S_ISVTX __S_ISVTX
#define S_IRUSR __S_IREAD
#define S_IWUSR __S_IWRITE
#define S_IXUSR __S_IEXEC
#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
#define S_IEXEC S_IXUSR
#define S_IRGRP (S_IRUSR >> 3)
#define S_IWGRP (S_IWUSR >> 3)
#define S_IXGRP (S_IXUSR >> 3)
#define S_IRWXG (S_IRWXU >> 3)
#define S_IROTH (S_IRGRP >> 3)
#define S_IWOTH (S_IWGRP >> 3)
#define S_IXOTH (S_IXGRP >> 3)
#define S_IRWXO (S_IRWXG >> 3)
#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#define S_BLKSIZE 512
#define _MKNOD_VER 0
#define _LINUX_STAT_H
#define _LINUX_TYPES_H
#define _ASM_X86_TYPES_H
#define _ASM_GENERIC_TYPES_H
#define _ASM_GENERIC_INT_LL64_H
#define __ASM_X86_BITSPERLONG_H
#define __BITS_PER_LONG 64
#define __ASM_GENERIC_BITS_PER_LONG
#define _LINUX_POSIX_TYPES_H
#define _LINUX_STDDEF_H
#define __struct_group(TAG,NAME,ATTRS,MEMBERS...) union { struct { MEMBERS } ATTRS; struct TAG { MEMBERS } ATTRS NAME; }
#define __DECLARE_FLEX_ARRAY(TYPE,NAME) struct { struct { } __empty_ ## NAME; TYPE NAME[]; }
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
#define _ASM_X86_POSIX_TYPES_64_H
#define __kernel_old_uid_t __kernel_old_uid_t
#define __kernel_old_dev_t __kernel_old_dev_t
#define __ASM_GENERIC_POSIX_TYPES_H
#define __bitwise__
#define __bitwise __bitwise__
#define __aligned_u64 __u64 __attribute__((aligned(8)))
#define __aligned_be64 __be64 __attribute__((aligned(8)))
#define __aligned_le64 __le64 __attribute__((aligned(8)))
#define STATX_TYPE 0x00000001U
#define STATX_MODE 0x00000002U
#define STATX_NLINK 0x00000004U
#define STATX_UID 0x00000008U
#define STATX_GID 0x00000010U
#define STATX_ATIME 0x00000020U
#define STATX_MTIME 0x00000040U
#define STATX_CTIME 0x00000080U
#define STATX_INO 0x00000100U
#define STATX_SIZE 0x00000200U
#define STATX_BLOCKS 0x00000400U
#define STATX_BASIC_STATS 0x000007ffU
#define STATX_BTIME 0x00000800U
#define STATX_ALL 0x00000fffU
#define STATX__RESERVED 0x80000000U
#define STATX_ATTR_COMPRESSED 0x00000004
#define STATX_ATTR_IMMUTABLE 0x00000010
#define STATX_ATTR_APPEND 0x00000020
#define STATX_ATTR_NODUMP 0x00000040
#define STATX_ATTR_ENCRYPTED 0x00000800
#define STATX_ATTR_AUTOMOUNT 0x00001000
#define STATX_ATTR_DAX 0x00200000
#define __statx_timestamp_defined 1
#define __statx_defined 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#undef __need_size_t
#define __wchar_t__
#define __WCHAR_T__
#define _WCHAR_T
#define _T_WCHAR_
#define _T_WCHAR
#define __WCHAR_T
#define _WCHAR_T_
#define _BSD_WCHAR_T_
#define _WCHAR_T_DEFINED_
#define _WCHAR_T_DEFINED
#define _WCHAR_T_H
#define ___int_wchar_t_h
#define __INT_WCHAR_T_H
#define _GCC_WCHAR_T
#define _WCHAR_T_DECLARED
#undef _BSD_WCHAR_T_
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define _STDLIB_H 1
#define WNOHANG 1
#define WUNTRACED 2
#define WSTOPPED 2
#define WEXITED 4
#define WCONTINUED 8
#define WNOWAIT 0x01000000
#define __WNOTHREAD 0x20000000
#define __WALL 0x40000000
#define __WCLONE 0x80000000
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
#define __WTERMSIG(status) ((status) & 0x7f)
#define __WSTOPSIG(status) __WEXITSTATUS(status)
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
#define __WIFSIGNALED(status) (((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
#define __WIFCONTINUED(status) ((status) == __W_CONTINUED)
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
#define __W_EXITCODE(ret,sig) ((ret) << 8 | (sig))
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#define __W_CONTINUED 0xffff
#define __WCOREFLAG 0x80
#define WEXITSTATUS(status) __WEXITSTATUS (status)
#define WTERMSIG(status) __WTERMSIG (status)
#define WSTOPSIG(status) __WSTOPSIG (status)
#define WIFEXITED(status) __WIFEXITED (status)
#define WIFSIGNALED(status) __WIFSIGNALED (status)
#define WIFSTOPPED(status) __WIFSTOPPED (status)
#define WIFCONTINUED(status) __WIFCONTINUED (status)
#define _BITS_FLOATN_H
#define __HAVE_FLOAT128 1
#define __HAVE_DISTINCT_FLOAT128 1
#define __HAVE_FLOAT64X 1
#define __HAVE_FLOAT64X_LONG_DOUBLE 1
#define __f128(x) x ##f128
#define __CFLOAT128 _Complex _Float128
#define _BITS_FLOATN_COMMON_H
#define __HAVE_FLOAT16 0
#define __HAVE_FLOAT32 1
#define __HAVE_FLOAT64 1
#define __HAVE_FLOAT32X 1
#define __HAVE_FLOAT128X 0
#define __HAVE_DISTINCT_FLOAT16 __HAVE_FLOAT16
#define __HAVE_DISTINCT_FLOAT32 0
#define __HAVE_DISTINCT_FLOAT64 0
#define __HAVE_DISTINCT_FLOAT32X 0
#define __HAVE_DISTINCT_FLOAT64X 0
#define __HAVE_DISTINCT_FLOAT128X __HAVE_FLOAT128X
#define __HAVE_FLOAT128_UNLIKE_LDBL (__HAVE_DISTINCT_FLOAT128 && __LDBL_MANT_DIG__ != 113)
#define __HAVE_FLOATN_NOT_TYPEDEF 1
#define __f32(x) x ##f32
#define __f64(x) x ##f64
#define __f32x(x) x ##f32x
#define __f64x(x) x ##f64x
#define __CFLOAT32 _Complex _Float32
#define __CFLOAT64 _Complex _Float64
#define __CFLOAT32X _Complex _Float32x
#define __CFLOAT64X _Complex _Float64x
#define __ldiv_t_defined 1
#define __lldiv_t_defined 1
#define RAND_MAX 2147483647
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#define MB_CUR_MAX (__ctype_get_mb_cur_max ())
#define _BITS_TYPES_LOCALE_T_H 1
#define _BITS_TYPES___LOCALE_T_H 1
#define _ALLOCA_H 1
#define __need_size_t
#undef __need_size_t
#undef __need_NULL
#undef alloca
#define alloca(size) __builtin_alloca (size)
#define __COMPAR_FN_T
#define __STDLIB_MB_LEN_MAX 16
#define _STDDEF_H
#define _STDDEF_H_
#define _ANSI_STDDEF_H
#define _PTRDIFF_T
#define _T_PTRDIFF_
#define _T_PTRDIFF
#define __PTRDIFF_T
#define _PTRDIFF_T_
#define _BSD_PTRDIFF_T_
#define ___int_ptrdiff_t_h
#define _GCC_PTRDIFF_T
#define _PTRDIFF_T_DECLARED
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define _GCC_MAX_ALIGN_T
#define _STRING_H 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define __need_size_t
#define __need_NULL
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define strdupa(s) (__extension__ ({ const char *__old = (s); size_t __len = strlen (__old) + 1; char *__new = (char *) __builtin_alloca (__len); (char *) memcpy (__new, __old, __len); }))
#define strndupa(s,n) (__extension__ ({ const char *__old = (s); size_t __len = strnlen (__old, (n)); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len); }))
#define _STRINGS_H 1
#define __need_size_t
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define __STRINGS_FORTIFIED 1
#define _BITS_STRING_FORTIFIED_H 1
#define _INTTYPES_H 1
#define _STDINT_H 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define _BITS_WCHAR_H 1
#define __WCHAR_MAX __WCHAR_MAX__
#define __WCHAR_MIN __WCHAR_MIN__
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define _BITS_STDINT_UINTN_H 1
#define __intptr_t_defined
#define __INT64_C(c) c ## L
#define __UINT64_C(c) c ## UL
#define INT8_MIN (-128)
#define INT16_MIN (-32767-1)
#define INT32_MIN (-2147483647-1)
#define INT64_MIN (-__INT64_C(9223372036854775807)-1)
#define INT8_MAX (127)
#define INT16_MAX (32767)
#define INT32_MAX (2147483647)
#define INT64_MAX (__INT64_C(9223372036854775807))
#define UINT8_MAX (255)
#define UINT16_MAX (65535)
#define UINT32_MAX (4294967295U)
#define UINT64_MAX (__UINT64_C(18446744073709551615))
#define INT_LEAST8_MIN (-128)
#define INT_LEAST16_MIN (-32767-1)
#define INT_LEAST32_MIN (-2147483647-1)
#define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1)
#define INT_LEAST8_MAX (127)
#define INT_LEAST16_MAX (32767)
#define INT_LEAST32_MAX (2147483647)
#define INT_LEAST64_MAX (__INT64_C(9223372036854775807))
#define UINT_LEAST8_MAX (255)
#define UINT_LEAST16_MAX (65535)
#define UINT_LEAST32_MAX (4294967295U)
#define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
#define INT_FAST8_MIN (-128)
#define INT_FAST16_MIN (-9223372036854775807L-1)
#define INT_FAST32_MIN (-9223372036854775807L-1)
#define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1)
#define INT_FAST8_MAX (127)
#define INT_FAST16_MAX (9223372036854775807L)
#define INT_FAST32_MAX (9223372036854775807L)
#define INT_FAST64_MAX (__INT64_C(9223372036854775807))
#define UINT_FAST8_MAX (255)
#define UINT_FAST16_MAX (18446744073709551615UL)
#define UINT_FAST32_MAX (18446744073709551615UL)
#define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
#define INTPTR_MIN (-9223372036854775807L-1)
#define INTPTR_MAX (9223372036854775807L)
#define UINTPTR_MAX (18446744073709551615UL)
#define INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
#define INTMAX_MAX (__INT64_C(9223372036854775807))
#define UINTMAX_MAX (__UINT64_C(18446744073709551615))
#define PTRDIFF_MIN (-9223372036854775807L-1)
#define PTRDIFF_MAX (9223372036854775807L)
#define SIG_ATOMIC_MIN (-2147483647-1)
#define SIG_ATOMIC_MAX (2147483647)
#define SIZE_MAX (18446744073709551615UL)
#define WCHAR_MIN __WCHAR_MIN
#define WCHAR_MAX __WCHAR_MAX
#define WINT_MIN (0u)
#define WINT_MAX (4294967295u)
#define INT8_C(c) c
#define INT16_C(c) c
#define INT32_C(c) c
#define INT64_C(c) c ## L
#define UINT8_C(c) c
#define UINT16_C(c) c
#define UINT32_C(c) c ## U
#define UINT64_C(c) c ## UL
#define INTMAX_C(c) c ## L
#define UINTMAX_C(c) c ## UL
#define INT8_WIDTH 8
#define UINT8_WIDTH 8
#define INT16_WIDTH 16
#define UINT16_WIDTH 16
#define INT32_WIDTH 32
#define UINT32_WIDTH 32
#define INT64_WIDTH 64
#define UINT64_WIDTH 64
#define INT_LEAST8_WIDTH 8
#define UINT_LEAST8_WIDTH 8
#define INT_LEAST16_WIDTH 16
#define UINT_LEAST16_WIDTH 16
#define INT_LEAST32_WIDTH 32
#define UINT_LEAST32_WIDTH 32
#define INT_LEAST64_WIDTH 64
#define UINT_LEAST64_WIDTH 64
#define INT_FAST8_WIDTH 8
#define UINT_FAST8_WIDTH 8
#define INT_FAST16_WIDTH __WORDSIZE
#define UINT_FAST16_WIDTH __WORDSIZE
#define INT_FAST32_WIDTH __WORDSIZE
#define UINT_FAST32_WIDTH __WORDSIZE
#define INT_FAST64_WIDTH 64
#define UINT_FAST64_WIDTH 64
#define INTPTR_WIDTH __WORDSIZE
#define UINTPTR_WIDTH __WORDSIZE
#define INTMAX_WIDTH 64
#define UINTMAX_WIDTH 64
#define PTRDIFF_WIDTH __WORDSIZE
#define SIG_ATOMIC_WIDTH 32
#define SIZE_WIDTH __WORDSIZE
#define WCHAR_WIDTH 32
#define WINT_WIDTH 32
#define _GCC_WRAP_STDINT_H
#define ____gwchar_t_defined 1
#define __PRI64_PREFIX "l"
#define __PRIPTR_PREFIX "l"
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 __PRI64_PREFIX "d"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "d"
#define PRIdLEAST64 __PRI64_PREFIX "d"
#define PRIdFAST8 "d"
#define PRIdFAST16 __PRIPTR_PREFIX "d"
#define PRIdFAST32 __PRIPTR_PREFIX "d"
#define PRIdFAST64 __PRI64_PREFIX "d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 __PRI64_PREFIX "i"
#define PRIiLEAST8 "i"
#define PRIiLEAST16 "i"
#define PRIiLEAST32 "i"
#define PRIiLEAST64 __PRI64_PREFIX "i"
#define PRIiFAST8 "i"
#define PRIiFAST16 __PRIPTR_PREFIX "i"
#define PRIiFAST32 __PRIPTR_PREFIX "i"
#define PRIiFAST64 __PRI64_PREFIX "i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 __PRI64_PREFIX "o"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "o"
#define PRIoLEAST64 __PRI64_PREFIX "o"
#define PRIoFAST8 "o"
#define PRIoFAST16 __PRIPTR_PREFIX "o"
#define PRIoFAST32 __PRIPTR_PREFIX "o"
#define PRIoFAST64 __PRI64_PREFIX "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 __PRI64_PREFIX "u"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "u"
#define PRIuLEAST64 __PRI64_PREFIX "u"
#define PRIuFAST8 "u"
#define PRIuFAST16 __PRIPTR_PREFIX "u"
#define PRIuFAST32 __PRIPTR_PREFIX "u"
#define PRIuFAST64 __PRI64_PREFIX "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 __PRI64_PREFIX "x"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "x"
#define PRIxLEAST64 __PRI64_PREFIX "x"
#define PRIxFAST8 "x"
#define PRIxFAST16 __PRIPTR_PREFIX "x"
#define PRIxFAST32 __PRIPTR_PREFIX "x"
#define PRIxFAST64 __PRI64_PREFIX "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 __PRI64_PREFIX "X"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "X"
#define PRIXLEAST64 __PRI64_PREFIX "X"
#define PRIXFAST8 "X"
#define PRIXFAST16 __PRIPTR_PREFIX "X"
#define PRIXFAST32 __PRIPTR_PREFIX "X"
#define PRIXFAST64 __PRI64_PREFIX "X"
#define PRIdMAX __PRI64_PREFIX "d"
#define PRIiMAX __PRI64_PREFIX "i"
#define PRIoMAX __PRI64_PREFIX "o"
#define PRIuMAX __PRI64_PREFIX "u"
#define PRIxMAX __PRI64_PREFIX "x"
#define PRIXMAX __PRI64_PREFIX "X"
#define PRIdPTR __PRIPTR_PREFIX "d"
#define PRIiPTR __PRIPTR_PREFIX "i"
#define PRIoPTR __PRIPTR_PREFIX "o"
#define PRIuPTR __PRIPTR_PREFIX "u"
#define PRIxPTR __PRIPTR_PREFIX "x"
#define PRIXPTR __PRIPTR_PREFIX "X"
#define SCNd8 "hhd"
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 __PRI64_PREFIX "d"
#define SCNdLEAST8 "hhd"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 __PRI64_PREFIX "d"
#define SCNdFAST8 "hhd"
#define SCNdFAST16 __PRIPTR_PREFIX "d"
#define SCNdFAST32 __PRIPTR_PREFIX "d"
#define SCNdFAST64 __PRI64_PREFIX "d"
#define SCNi8 "hhi"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 __PRI64_PREFIX "i"
#define SCNiLEAST8 "hhi"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 __PRI64_PREFIX "i"
#define SCNiFAST8 "hhi"
#define SCNiFAST16 __PRIPTR_PREFIX "i"
#define SCNiFAST32 __PRIPTR_PREFIX "i"
#define SCNiFAST64 __PRI64_PREFIX "i"
#define SCNu8 "hhu"
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 __PRI64_PREFIX "u"
#define SCNuLEAST8 "hhu"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 __PRI64_PREFIX "u"
#define SCNuFAST8 "hhu"
#define SCNuFAST16 __PRIPTR_PREFIX "u"
#define SCNuFAST32 __PRIPTR_PREFIX "u"
#define SCNuFAST64 __PRI64_PREFIX "u"
#define SCNo8 "hho"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 __PRI64_PREFIX "o"
#define SCNoLEAST8 "hho"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 __PRI64_PREFIX "o"
#define SCNoFAST8 "hho"
#define SCNoFAST16 __PRIPTR_PREFIX "o"
#define SCNoFAST32 __PRIPTR_PREFIX "o"
#define SCNoFAST64 __PRI64_PREFIX "o"
#define SCNx8 "hhx"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 __PRI64_PREFIX "x"
#define SCNxLEAST8 "hhx"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 __PRI64_PREFIX "x"
#define SCNxFAST8 "hhx"
#define SCNxFAST16 __PRIPTR_PREFIX "x"
#define SCNxFAST32 __PRIPTR_PREFIX "x"
#define SCNxFAST64 __PRI64_PREFIX "x"
#define SCNdMAX __PRI64_PREFIX "d"
#define SCNiMAX __PRI64_PREFIX "i"
#define SCNoMAX __PRI64_PREFIX "o"
#define SCNuMAX __PRI64_PREFIX "u"
#define SCNxMAX __PRI64_PREFIX "x"
#define SCNdPTR __PRIPTR_PREFIX "d"
#define SCNiPTR __PRIPTR_PREFIX "i"
#define SCNoPTR __PRIPTR_PREFIX "o"
#define SCNuPTR __PRIPTR_PREFIX "u"
#define SCNxPTR __PRIPTR_PREFIX "x"
#define _STDALIGN_H
#define alignas _Alignas
#define alignof _Alignof
#define __alignas_is_defined 1
#define __alignof_is_defined 1
#define _UNISTD_H 1
#define _POSIX_VERSION 200809L
#define __POSIX2_THIS_VERSION 200809L
#define _POSIX2_VERSION __POSIX2_THIS_VERSION
#define _POSIX2_C_VERSION __POSIX2_THIS_VERSION
#define _POSIX2_C_BIND __POSIX2_THIS_VERSION
#define _POSIX2_C_DEV __POSIX2_THIS_VERSION
#define _POSIX2_SW_DEV __POSIX2_THIS_VERSION
#define _POSIX2_LOCALEDEF __POSIX2_THIS_VERSION
#define _XOPEN_VERSION 700
#define _XOPEN_XCU_VERSION 4
#define _XOPEN_XPG2 1
#define _XOPEN_XPG3 1
#define _XOPEN_XPG4 1
#define _XOPEN_UNIX 1
#define _XOPEN_ENH_I18N 1
#define _XOPEN_LEGACY 1
#define _BITS_POSIX_OPT_H 1
#define _POSIX_JOB_CONTROL 1
#define _POSIX_SAVED_IDS 1
#define _POSIX_PRIORITY_SCHEDULING 200809L
#define _POSIX_SYNCHRONIZED_IO 200809L
#define _POSIX_FSYNC 200809L
#define _POSIX_MAPPED_FILES 200809L
#define _POSIX_MEMLOCK 200809L
#define _POSIX_MEMLOCK_RANGE 200809L
#define _POSIX_MEMORY_PROTECTION 200809L
#define _POSIX_CHOWN_RESTRICTED 0
#define _POSIX_VDISABLE '\0'
#define _POSIX_NO_TRUNC 1
#define _XOPEN_REALTIME 1
#define _XOPEN_REALTIME_THREADS 1
#define _XOPEN_SHM 1
#define _POSIX_THREADS 200809L
#define _POSIX_REENTRANT_FUNCTIONS 1
#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
#define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
#define _POSIX_THREAD_ATTR_STACKSIZE 200809L
#define _POSIX_THREAD_ATTR_STACKADDR 200809L
#define _POSIX_THREAD_PRIO_INHERIT 200809L
#define _POSIX_THREAD_PRIO_PROTECT 200809L
#define _POSIX_THREAD_ROBUST_PRIO_INHERIT 200809L
#define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1
#define _POSIX_SEMAPHORES 200809L
#define _POSIX_REALTIME_SIGNALS 200809L
#define _POSIX_ASYNCHRONOUS_IO 200809L
#define _POSIX_ASYNC_IO 1
#define _LFS_ASYNCHRONOUS_IO 1
#define _POSIX_PRIORITIZED_IO 200809L
#define _LFS64_ASYNCHRONOUS_IO 1
#define _LFS_LARGEFILE 1
#define _LFS64_LARGEFILE 1
#define _LFS64_STDIO 1
#define _POSIX_SHARED_MEMORY_OBJECTS 200809L
#define _POSIX_CPUTIME 0
#define _POSIX_THREAD_CPUTIME 0
#define _POSIX_REGEXP 1
#define _POSIX_READER_WRITER_LOCKS 200809L
#define _POSIX_SHELL 1
#define _POSIX_TIMEOUTS 200809L
#define _POSIX_SPIN_LOCKS 200809L
#define _POSIX_SPAWN 200809L
#define _POSIX_TIMERS 200809L
#define _POSIX_BARRIERS 200809L
#define _POSIX_MESSAGE_PASSING 200809L
#define _POSIX_THREAD_PROCESS_SHARED 200809L
#define _POSIX_MONOTONIC_CLOCK 0
#define _POSIX_CLOCK_SELECTION 200809L
#define _POSIX_ADVISORY_INFO 200809L
#define _POSIX_IPV6 200809L
#define _POSIX_RAW_SOCKETS 200809L
#define _POSIX2_CHAR_TERM 200809L
#define _POSIX_SPORADIC_SERVER -1
#define _POSIX_THREAD_SPORADIC_SERVER -1
#define _POSIX_TRACE -1
#define _POSIX_TRACE_EVENT_FILTER -1
#define _POSIX_TRACE_INHERIT -1
#define _POSIX_TRACE_LOG -1
#define _POSIX_TYPED_MEMORY_OBJECTS -1
#define _XOPEN_STREAMS -1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define _POSIX_V7_LPBIG_OFFBIG -1
#define _POSIX_V6_LPBIG_OFFBIG -1
#define _XBS5_LPBIG_OFFBIG -1
#define _POSIX_V7_LP64_OFF64 1
#define _POSIX_V6_LP64_OFF64 1
#define _XBS5_LP64_OFF64 1
#define __ILP32_OFF32_CFLAGS "-m32"
#define __ILP32_OFF32_LDFLAGS "-m32"
#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
#define __ILP32_OFFBIG_LDFLAGS "-m32"
#define __LP64_OFF64_CFLAGS "-m64"
#define __LP64_OFF64_LDFLAGS "-m64"
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define __need_size_t
#define __need_NULL
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define __socklen_t_defined
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#define L_SET SEEK_SET
#define L_INCR SEEK_CUR
#define L_XTND SEEK_END
#define _PC_LINK_MAX _PC_LINK_MAX
#define _PC_MAX_CANON _PC_MAX_CANON
#define _PC_MAX_INPUT _PC_MAX_INPUT
#define _PC_NAME_MAX _PC_NAME_MAX
#define _PC_PATH_MAX _PC_PATH_MAX
#define _PC_PIPE_BUF _PC_PIPE_BUF
#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED
#define _PC_NO_TRUNC _PC_NO_TRUNC
#define _PC_VDISABLE _PC_VDISABLE
#define _PC_SYNC_IO _PC_SYNC_IO
#define _PC_ASYNC_IO _PC_ASYNC_IO
#define _PC_PRIO_IO _PC_PRIO_IO
#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF
#define _PC_FILESIZEBITS _PC_FILESIZEBITS
#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE
#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE
#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE
#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN
#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN
#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX
#define _PC_2_SYMLINKS _PC_2_SYMLINKS
#define _SC_ARG_MAX _SC_ARG_MAX
#define _SC_CHILD_MAX _SC_CHILD_MAX
#define _SC_CLK_TCK _SC_CLK_TCK
#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX
#define _SC_OPEN_MAX _SC_OPEN_MAX
#define _SC_STREAM_MAX _SC_STREAM_MAX
#define _SC_TZNAME_MAX _SC_TZNAME_MAX
#define _SC_JOB_CONTROL _SC_JOB_CONTROL
#define _SC_SAVED_IDS _SC_SAVED_IDS
#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS
#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING
#define _SC_TIMERS _SC_TIMERS
#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO
#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO
#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO
#define _SC_FSYNC _SC_FSYNC
#define _SC_MAPPED_FILES _SC_MAPPED_FILES
#define _SC_MEMLOCK _SC_MEMLOCK
#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE
#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION
#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING
#define _SC_SEMAPHORES _SC_SEMAPHORES
#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS
#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX
#define _SC_AIO_MAX _SC_AIO_MAX
#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX
#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX
#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX
#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX
#define _SC_VERSION _SC_VERSION
#define _SC_PAGESIZE _SC_PAGESIZE
#define _SC_PAGE_SIZE _SC_PAGESIZE
#define _SC_RTSIG_MAX _SC_RTSIG_MAX
#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX
#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX
#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX
#define _SC_TIMER_MAX _SC_TIMER_MAX
#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX
#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX
#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX
#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX
#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX
#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX
#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX
#define _SC_LINE_MAX _SC_LINE_MAX
#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX
#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX
#define _SC_2_VERSION _SC_2_VERSION
#define _SC_2_C_BIND _SC_2_C_BIND
#define _SC_2_C_DEV _SC_2_C_DEV
#define _SC_2_FORT_DEV _SC_2_FORT_DEV
#define _SC_2_FORT_RUN _SC_2_FORT_RUN
#define _SC_2_SW_DEV _SC_2_SW_DEV
#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF
#define _SC_PII _SC_PII
#define _SC_PII_XTI _SC_PII_XTI
#define _SC_PII_SOCKET _SC_PII_SOCKET
#define _SC_PII_INTERNET _SC_PII_INTERNET
#define _SC_PII_OSI _SC_PII_OSI
#define _SC_POLL _SC_POLL
#define _SC_SELECT _SC_SELECT
#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV
#define _SC_IOV_MAX _SC_IOV_MAX
#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM
#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM
#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS
#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS
#define _SC_PII_OSI_M _SC_PII_OSI_M
#define _SC_T_IOV_MAX _SC_T_IOV_MAX
#define _SC_THREADS _SC_THREADS
#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS
#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX
#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX
#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX
#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX
#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX
#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN
#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX
#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR
#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE
#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING
#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT
#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT
#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED
#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF
#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN
#define _SC_PHYS_PAGES _SC_PHYS_PAGES
#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES
#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX
#define _SC_PASS_MAX _SC_PASS_MAX
#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION
#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION
#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX
#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT
#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N
#define _SC_XOPEN_SHM _SC_XOPEN_SHM
#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM
#define _SC_2_C_VERSION _SC_2_C_VERSION
#define _SC_2_UPE _SC_2_UPE
#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2
#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3
#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4
#define _SC_CHAR_BIT _SC_CHAR_BIT
#define _SC_CHAR_MAX _SC_CHAR_MAX
#define _SC_CHAR_MIN _SC_CHAR_MIN
#define _SC_INT_MAX _SC_INT_MAX
#define _SC_INT_MIN _SC_INT_MIN
#define _SC_LONG_BIT _SC_LONG_BIT
#define _SC_WORD_BIT _SC_WORD_BIT
#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX
#define _SC_NZERO _SC_NZERO
#define _SC_SSIZE_MAX _SC_SSIZE_MAX
#define _SC_SCHAR_MAX _SC_SCHAR_MAX
#define _SC_SCHAR_MIN _SC_SCHAR_MIN
#define _SC_SHRT_MAX _SC_SHRT_MAX
#define _SC_SHRT_MIN _SC_SHRT_MIN
#define _SC_UCHAR_MAX _SC_UCHAR_MAX
#define _SC_UINT_MAX _SC_UINT_MAX
#define _SC_ULONG_MAX _SC_ULONG_MAX
#define _SC_USHRT_MAX _SC_USHRT_MAX
#define _SC_NL_ARGMAX _SC_NL_ARGMAX
#define _SC_NL_LANGMAX _SC_NL_LANGMAX
#define _SC_NL_MSGMAX _SC_NL_MSGMAX
#define _SC_NL_NMAX _SC_NL_NMAX
#define _SC_NL_SETMAX _SC_NL_SETMAX
#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX
#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32
#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG
#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64
#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG
#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY
#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME
#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS
#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO
#define _SC_BARRIERS _SC_BARRIERS
#define _SC_BASE _SC_BASE
#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT
#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R
#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION
#define _SC_CPUTIME _SC_CPUTIME
#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME
#define _SC_DEVICE_IO _SC_DEVICE_IO
#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC
#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R
#define _SC_FD_MGMT _SC_FD_MGMT
#define _SC_FIFO _SC_FIFO
#define _SC_PIPE _SC_PIPE
#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES
#define _SC_FILE_LOCKING _SC_FILE_LOCKING
#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM
#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK
#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS
#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS
#define _SC_NETWORKING _SC_NETWORKING
#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS
#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS
#define _SC_REGEXP _SC_REGEXP
#define _SC_REGEX_VERSION _SC_REGEX_VERSION
#define _SC_SHELL _SC_SHELL
#define _SC_SIGNALS _SC_SIGNALS
#define _SC_SPAWN _SC_SPAWN
#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER
#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER
#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE
#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R
#define _SC_TIMEOUTS _SC_TIMEOUTS
#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS
#define _SC_USER_GROUPS _SC_USER_GROUPS
#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R
#define _SC_2_PBS _SC_2_PBS
#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING
#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE
#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE
#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK
#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX
#define _SC_STREAMS _SC_STREAMS
#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT
#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32
#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG
#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64
#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG
#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
#define _SC_TRACE _SC_TRACE
#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER
#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT
#define _SC_TRACE_LOG _SC_TRACE_LOG
#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE
#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC
#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE
#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE
#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC
#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE
#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE
#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC
#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE
#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE
#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC
#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE
#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE
#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC
#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE
#define _SC_IPV6 _SC_IPV6
#define _SC_RAW_SOCKETS _SC_RAW_SOCKETS
#define _SC_V7_ILP32_OFF32 _SC_V7_ILP32_OFF32
#define _SC_V7_ILP32_OFFBIG _SC_V7_ILP32_OFFBIG
#define _SC_V7_LP64_OFF64 _SC_V7_LP64_OFF64
#define _SC_V7_LPBIG_OFFBIG _SC_V7_LPBIG_OFFBIG
#define _SC_SS_REPL_MAX _SC_SS_REPL_MAX
#define _SC_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX
#define _SC_TRACE_NAME_MAX _SC_TRACE_NAME_MAX
#define _SC_TRACE_SYS_MAX _SC_TRACE_SYS_MAX
#define _SC_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX
#define _SC_XOPEN_STREAMS _SC_XOPEN_STREAMS
#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT
#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT
#define _CS_PATH _CS_PATH
#define _CS_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
#define _CS_GNU_LIBC_VERSION _CS_GNU_LIBC_VERSION
#define _CS_GNU_LIBPTHREAD_VERSION _CS_GNU_LIBPTHREAD_VERSION
#define _CS_V5_WIDTH_RESTRICTED_ENVS _CS_V5_WIDTH_RESTRICTED_ENVS
#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS _CS_V5_WIDTH_RESTRICTED_ENVS
#define _CS_V7_WIDTH_RESTRICTED_ENVS _CS_V7_WIDTH_RESTRICTED_ENVS
#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS _CS_V7_WIDTH_RESTRICTED_ENVS
#define _CS_LFS_CFLAGS _CS_LFS_CFLAGS
#define _CS_LFS_LDFLAGS _CS_LFS_LDFLAGS
#define _CS_LFS_LIBS _CS_LFS_LIBS
#define _CS_LFS_LINTFLAGS _CS_LFS_LINTFLAGS
#define _CS_LFS64_CFLAGS _CS_LFS64_CFLAGS
#define _CS_LFS64_LDFLAGS _CS_LFS64_LDFLAGS
#define _CS_LFS64_LIBS _CS_LFS64_LIBS
#define _CS_LFS64_LINTFLAGS _CS_LFS64_LINTFLAGS
#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_XBS5_ILP32_OFF32_CFLAGS
#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_XBS5_ILP32_OFF32_LDFLAGS
#define _CS_XBS5_ILP32_OFF32_LIBS _CS_XBS5_ILP32_OFF32_LIBS
#define _CS_XBS5_ILP32_OFF32_LINTFLAGS _CS_XBS5_ILP32_OFF32_LINTFLAGS
#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_XBS5_ILP32_OFFBIG_CFLAGS
#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_XBS5_ILP32_OFFBIG_LDFLAGS
#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_XBS5_ILP32_OFFBIG_LIBS
#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_XBS5_LP64_OFF64_CFLAGS
#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_XBS5_LP64_OFF64_LDFLAGS
#define _CS_XBS5_LP64_OFF64_LIBS _CS_XBS5_LP64_OFF64_LIBS
#define _CS_XBS5_LP64_OFF64_LINTFLAGS _CS_XBS5_LP64_OFF64_LINTFLAGS
#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_XBS5_LPBIG_OFFBIG_CFLAGS
#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_XBS5_LPBIG_OFFBIG_LIBS
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V6_ILP32_OFF32_CFLAGS
#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V6_ILP32_OFF32_LIBS
#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V6_ILP32_OFFBIG_LIBS
#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V6_LP64_OFF64_CFLAGS
#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V6_LP64_OFF64_LDFLAGS
#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V6_LP64_OFF64_LIBS
#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS _CS_POSIX_V7_ILP32_OFF32_CFLAGS
#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS _CS_POSIX_V7_ILP32_OFF32_LDFLAGS
#define _CS_POSIX_V7_ILP32_OFF32_LIBS _CS_POSIX_V7_ILP32_OFF32_LIBS
#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS
#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS
#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS
#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS _CS_POSIX_V7_ILP32_OFFBIG_LIBS
#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS
#define _CS_POSIX_V7_LP64_OFF64_CFLAGS _CS_POSIX_V7_LP64_OFF64_CFLAGS
#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS _CS_POSIX_V7_LP64_OFF64_LDFLAGS
#define _CS_POSIX_V7_LP64_OFF64_LIBS _CS_POSIX_V7_LP64_OFF64_LIBS
#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS _CS_POSIX_V7_LP64_OFF64_LINTFLAGS
#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS
#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS
#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS _CS_POSIX_V7_LPBIG_OFFBIG_LIBS
#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS
#define _CS_V6_ENV _CS_V6_ENV
#define _CS_V7_ENV _CS_V7_ENV
#define _GETOPT_POSIX_H 1
#define _GETOPT_CORE_H 1
#define F_ULOCK 0
#define F_LOCK 1
#define F_TLOCK 2
#define F_TEST 3
#define TEMP_FAILURE_RETRY(expression) (__extension__ ({ long int __result; do __result = (long int) (expression); while (__result == -1L && errno == EINTR); __result; }))
#define RBIMPL_DLLEXPORT_H
#undef RUBY_EXTERN
#define RUBY_EXTERN extern
#define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
#define MJIT_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
#define MJIT_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
#define MJIT_STATIC static
#define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN
#define RBIMPL_SYMBOL_EXPORT_END() RUBY_SYMBOL_EXPORT_END
#define RBIMPL_XMALLOC_H
#define RBIMPL_ATTR_ALLOC_SIZE_H
#define RBIMPL_HAS_ATTRIBUTE_H
#define RBIMPL_HAVE___HAS_ATTRIBUTE 1
#define RBIMPL_HAS_ATTRIBUTE(_) __has_attribute(_)
#define RBIMPL_ATTR_ALLOC_SIZE(tuple) __attribute__((__alloc_size__ tuple))
#define RBIMPL_ATTR_NODISCARD_H
#define RBIMPL_HAS_C_ATTRIBUTE_H
#define RBIMPL_HAS_C_ATTRIBUTE(_) 0
#define RBIMPL_HAS_CPP_ATTRIBUTE_H
#define RBIMPL_HAS_CPP_ATTRIBUTE0(_) __has_cpp_attribute(_)
#define RBIMPL_HAS_CPP_ATTRIBUTE(_) 0
#define RBIMPL_ATTR_NODISCARD() __attribute__((__warn_unused_result__))
#define RBIMPL_ATTR_NOEXCEPT_H
#define RBIMPL_HAS_FEATURE_H
#define RBIMPL_HAS_FEATURE(_) 0
#define RBIMPL_ATTR_NOEXCEPT(_)
#define RBIMPL_ATTR_RESTRICT_H
#define RBIMPL_ATTR_RESTRICT() __attribute__((__malloc__))
#define RBIMPL_ATTR_RETURNS_NONNULL_H
#define RBIMPL_ATTR_RETURNS_NONNULL() __attribute__((__returns_nonnull__))
#define USE_GC_MALLOC_OBJ_INFO_DETAILS 0
#define xmalloc ruby_xmalloc
#define xmalloc2 ruby_xmalloc2
#define xcalloc ruby_xcalloc
#define xrealloc ruby_xrealloc
#define xrealloc2 ruby_xrealloc2
#define xfree ruby_xfree
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_BACKWARD2_ASSUME_H
#define RBIMPL_ASSUME_H
#define RBIMPL_CAST_H
#define RBIMPL_HAS_WARNING_H
#define RBIMPL_HAS_WARNING(_) 0
#define RBIMPL_WARNING_PUSH_H
#define RBIMPL_WARNING_PRAGMA0(x) _Pragma(#x)
#define RBIMPL_WARNING_PRAGMA1(x) RBIMPL_WARNING_PRAGMA0(GCC diagnostic x)
#define RBIMPL_WARNING_PRAGMA2(x,y) RBIMPL_WARNING_PRAGMA1(x #y)
#define RBIMPL_WARNING_PUSH() RBIMPL_WARNING_PRAGMA1(push)
#define RBIMPL_WARNING_POP() RBIMPL_WARNING_PRAGMA1(pop)
#define RBIMPL_WARNING_ERROR(flag) RBIMPL_WARNING_PRAGMA2(error, flag)
#define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)
#define RBIMPL_CAST(expr) (expr)
#define RBIMPL_HAS_BUILTIN_H
#define RBIMPL_HAS_BUILTIN(_) (RBIMPL_HAS_BUILTIN_ ## _)
#define RBIMPL_HAS_BUILTIN___builtin_add_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
#define RBIMPL_HAS_BUILTIN___builtin_alloca RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
#define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align RBIMPL_COMPILER_SINCE(GCC, 6, 1, 0)
#define RBIMPL_HAS_BUILTIN___builtin_assume 0
#define RBIMPL_HAS_BUILTIN___builtin_bswap16 RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
#define RBIMPL_HAS_BUILTIN___builtin_bswap32 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_bswap64 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_clz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_clzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_clzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_constant_p RBIMPL_COMPILER_SINCE(GCC, 2,95, 3)
#define RBIMPL_HAS_BUILTIN___builtin_ctz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_ctzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_ctzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_expect RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
#define RBIMPL_HAS_BUILTIN___builtin_mul_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
#define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
#define RBIMPL_HAS_BUILTIN___builtin_popcount RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_popcountl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_popcountll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#define RBIMPL_HAS_BUILTIN___builtin_rotateleft32 0
#define RBIMPL_HAS_BUILTIN___builtin_rotateleft64 0
#define RBIMPL_HAS_BUILTIN___builtin_rotateright32 0
#define RBIMPL_HAS_BUILTIN___builtin_rotateright64 0
#define RBIMPL_HAS_BUILTIN___builtin_sub_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
#define RBIMPL_HAS_BUILTIN___builtin_unreachable RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
#define RBIMPL_UNREACHABLE_RETURN(_) __builtin_unreachable()
#define RBIMPL_UNREACHABLE __builtin_unreachable
#define RBIMPL_ASSUME(_) (RB_LIKELY(!!(_)) ? RBIMPL_CAST((void)0) : RBIMPL_UNREACHABLE())
#define ASSUME RBIMPL_ASSUME
#define UNREACHABLE RBIMPL_UNREACHABLE()
#define UNREACHABLE_RETURN RBIMPL_UNREACHABLE_RETURN
#define RB_LIKELY(x) (__builtin_expect(!!(x), 1))
#define RB_UNLIKELY(x) (__builtin_expect(!!(x), 0))
#define RUBY_BACKWARD2_ATTRIBUTES_H
#define RBIMPL_ATTR_CONST_H
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) (RBIMPL_HAS_DECLSPEC_ATTRIBUTE_ ## _)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_align RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_deprecated RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllexport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllimport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_empty_bases RBIMPL_COMPILER_SINCE(MSVC,19, 0, 23918)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noalias RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(MSVC,11, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_restrict RBIMPL_COMPILER_SINCE(MSVC,14, 0, 0)
#undef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow
#define RBIMPL_ATTR_CONST() __attribute__((__const__))
#define RBIMPL_ATTR_CONST_UNLESS_DEBUG() RBIMPL_ATTR_CONST()
#define RBIMPL_ATTR_DEPRECATED_H
#define RBIMPL_HAS_EXTENSION_H
#define RBIMPL_HAS_EXTENSION(_) RBIMPL_HAS_FEATURE(_)
#define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
#define RBIMPL_ATTR_DEPRECATED_EXT(msg)
#define RBIMPL_ATTR_ERROR_H
#define RBIMPL_ATTR_ERROR(msg) __attribute__((__error__ msg))
#define RBIMPL_ATTR_FORCEINLINE_H
#define RBIMPL_ATTR_FORCEINLINE() __attribute__((__always_inline__)) inline
#define RBIMPL_ATTR_FORMAT_H
#define RBIMPL_ATTR_FORMAT(x,y,z) __attribute__((__format__(x, y, z)))
#define RBIMPL_PRINTF_FORMAT __printf__
#define RBIMPL_ATTR_MAYBE_UNUSED_H
#define RBIMPL_ATTR_MAYBE_UNUSED() __attribute__((__unused__))
#define RBIMPL_ATTR_NOINLINE_H
#define RBIMPL_ATTR_NOINLINE() __attribute__((__noinline__))
#define RBIMPL_ATTR_NONNULL_H
#define RBIMPL_ATTR_NONNULL(list) __attribute__((__nonnull__ list))
#define RBIMPL_NONNULL_ARG(arg) RBIMPL_ASSERT_NOTHING
#define RBIMPL_ATTR_NORETURN_H
#define RBIMPL_ATTR_NORETURN() __attribute__((__noreturn__))
#define RBIMPL_ATTR_PURE_H
#define RUBY_ASSERT_H
#define RBIMPL_RUBY_DEBUG 0
#define RBIMPL_NDEBUG 0
#undef RUBY_DEBUG
#undef RUBY_NDEBUG
#undef NDEBUG
#define RUBY_DEBUG 0
#define RUBY_NDEBUG 1
#define NDEBUG
#undef RBIMPL_NDEBUG
#undef RBIMPL_RUBY_DEBUG
#define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
#define RUBY_ASSERT_FAIL(mesg) rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
#define RUBY_ASSERT_MESG(expr,mesg) (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
#define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
#define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
#define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
#define RUBY_ASSERT_MESG_WHEN(cond,expr,mesg) ((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
#define RUBY_ASSERT_WHEN(cond,expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
#define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
#define RBIMPL_ATTR_PURE() __attribute__((__pure__))
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_PURE()
#define RBIMPL_ATTR_WARNING_H
#define RBIMPL_ATTR_WARNING(msg) __attribute__((__warning__ msg))
#undef CONSTFUNC
#define CONSTFUNC(x) RBIMPL_ATTR_CONST() x
#undef PUREFUNC
#define PUREFUNC(x) RBIMPL_ATTR_PURE() x
#undef DEPRECATED
#define DEPRECATED(x) RBIMPL_ATTR_DEPRECATED(("")) x
#undef DEPRECATED_BY
#define DEPRECATED_BY(n,x) RBIMPL_ATTR_DEPRECATED(("by: " #n)) x
#undef DEPRECATED_TYPE
#define DEPRECATED_TYPE(mesg,decl) _Pragma("message \"DEPRECATED_TYPE is deprecated\""); decl RBIMPL_ATTR_DEPRECATED(mseg)
#undef RUBY_CXX_DEPRECATED
#define RUBY_CXX_DEPRECATED(mseg) RBIMPL_ATTR_DEPRECATED((mseg))
#undef NOINLINE
#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x
#undef ERRORFUNC
#define ERRORFUNC(mesg,x) RBIMPL_ATTR_ERROR(mesg) x
#define HAVE_ATTRIBUTE_ERRORFUNC 1
#undef WARNINGFUNC
#define WARNINGFUNC(mesg,x) RBIMPL_ATTR_WARNING(mesg) x
#define HAVE_ATTRIBUTE_WARNINGFUNC 1
#undef COLDFUNC
#define PRINTF_ARGS(decl,string_index,first_to_check) RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, (string_index), (first_to_check)) decl
#undef RUBY_ATTR_ALLOC_SIZE
#define RUBY_ATTR_ALLOC_SIZE RBIMPL_ATTR_ALLOC_SIZE
#undef RUBY_ATTR_MALLOC
#define RUBY_ATTR_MALLOC RBIMPL_ATTR_RESTRICT()
#undef RUBY_ATTR_RETURNS_NONNULL
#define RUBY_ATTR_RETURNS_NONNULL RBIMPL_ATTR_RETURNS_NONNULL()
#define RUBY_ALIAS_FUNCTION(prot,name,args) RUBY_ALIAS_FUNCTION_TYPE(VALUE, prot, name, args)
#undef RUBY_FUNC_NONNULL
#define RUBY_FUNC_NONNULL(n,x) RBIMPL_ATTR_NONNULL(n) x
#undef NORETURN
#define NORETURN(x) RBIMPL_ATTR_NORETURN() x
#define NORETURN_STYLE_NEW
#define PACKED_STRUCT_UNALIGNED(x) PACKED_STRUCT(x)
#undef RB_UNUSED_VAR
#define RB_UNUSED_VAR(x) x RBIMPL_ATTR_MAYBE_UNUSED()
#define RUBY_BACKWARD2_BOOL_H
#define RBIMPL_STDBOOL_H
#define _STDBOOL_H
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#define FALSE false
#define TRUE true
#define RUBY_BACKWARD2_LONG_LONG_H
#define HAVE_TRUE_LONG_LONG 1
#define LONG_LONG long long
#define RUBY_BACKWARD2_STDALIGN_H
#define RBIMPL_STDALIGN_H
#define RBIMPL_ALIGNAS(_) __attribute__((__aligned__(_)))
#define RBIMPL_ALIGNOF(T) RB_GNUC_EXTENSION(_Alignof(T))
#undef RUBY_ALIGNAS
#undef RUBY_ALIGNOF
#define RUBY_ALIGNAS RBIMPL_ALIGNAS
#define RUBY_ALIGNOF RBIMPL_ALIGNOF
#define RUBY_BACKWARD2_STDARG_H
#undef _
#define _(args) args
#undef __
#define __(args) args
#define ANYARGS
#define RBIMPL_DOSISH_H
#define PATH_SEP ":"
#define PATH_SEP_CHAR PATH_SEP[0]
#define PATH_ENV "PATH"
#define CASEFOLD_FILESYSTEM 0
#define RUBY_MISSING_H 1
#define _MATH_H 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define _BITS_LIBM_SIMD_DECL_STUBS_H 1
#define __DECL_SIMD_cos
#define __DECL_SIMD_cosf
#define __DECL_SIMD_cosl
#define __DECL_SIMD_cosf16
#define __DECL_SIMD_cosf32
#define __DECL_SIMD_cosf64
#define __DECL_SIMD_cosf128
#define __DECL_SIMD_cosf32x
#define __DECL_SIMD_cosf64x
#define __DECL_SIMD_cosf128x
#define __DECL_SIMD_sin
#define __DECL_SIMD_sinf
#define __DECL_SIMD_sinl
#define __DECL_SIMD_sinf16
#define __DECL_SIMD_sinf32
#define __DECL_SIMD_sinf64
#define __DECL_SIMD_sinf128
#define __DECL_SIMD_sinf32x
#define __DECL_SIMD_sinf64x
#define __DECL_SIMD_sinf128x
#define __DECL_SIMD_sincos
#define __DECL_SIMD_sincosf
#define __DECL_SIMD_sincosl
#define __DECL_SIMD_sincosf16
#define __DECL_SIMD_sincosf32
#define __DECL_SIMD_sincosf64
#define __DECL_SIMD_sincosf128
#define __DECL_SIMD_sincosf32x
#define __DECL_SIMD_sincosf64x
#define __DECL_SIMD_sincosf128x
#define __DECL_SIMD_log
#define __DECL_SIMD_logf
#define __DECL_SIMD_logl
#define __DECL_SIMD_logf16
#define __DECL_SIMD_logf32
#define __DECL_SIMD_logf64
#define __DECL_SIMD_logf128
#define __DECL_SIMD_logf32x
#define __DECL_SIMD_logf64x
#define __DECL_SIMD_logf128x
#define __DECL_SIMD_exp
#define __DECL_SIMD_expf
#define __DECL_SIMD_expl
#define __DECL_SIMD_expf16
#define __DECL_SIMD_expf32
#define __DECL_SIMD_expf64
#define __DECL_SIMD_expf128
#define __DECL_SIMD_expf32x
#define __DECL_SIMD_expf64x
#define __DECL_SIMD_expf128x
#define __DECL_SIMD_pow
#define __DECL_SIMD_powf
#define __DECL_SIMD_powl
#define __DECL_SIMD_powf16
#define __DECL_SIMD_powf32
#define __DECL_SIMD_powf64
#define __DECL_SIMD_powf128
#define __DECL_SIMD_powf32x
#define __DECL_SIMD_powf64x
#define __DECL_SIMD_powf128x
#define HUGE_VAL (__builtin_huge_val ())
#define HUGE_VALF (__builtin_huge_valf ())
#define HUGE_VALL (__builtin_huge_vall ())
#define HUGE_VAL_F32 (__builtin_huge_valf32 ())
#define HUGE_VAL_F64 (__builtin_huge_valf64 ())
#define HUGE_VAL_F128 (__builtin_huge_valf128 ())
#define HUGE_VAL_F32X (__builtin_huge_valf32x ())
#define HUGE_VAL_F64X (__builtin_huge_valf64x ())
#define INFINITY (__builtin_inff ())
#define NAN (__builtin_nanf (""))
#define SNANF (__builtin_nansf (""))
#define SNAN (__builtin_nans (""))
#define SNANL (__builtin_nansl (""))
#define SNANF32 (__builtin_nansf32 (""))
#define SNANF64 (__builtin_nansf64 (""))
#define SNANF128 (__builtin_nansf128 (""))
#define SNANF32X (__builtin_nansf32x (""))
#define SNANF64X (__builtin_nansf64x (""))
#define __GLIBC_FLT_EVAL_METHOD __FLT_EVAL_METHOD__
#define __FP_LOGB0_IS_MIN 1
#define __FP_LOGBNAN_IS_MIN 1
#define FP_ILOGB0 (-2147483647 - 1)
#define FP_ILOGBNAN (-2147483647 - 1)
#define __FP_LONG_MAX 0x7fffffffffffffffL
#define FP_LLOGB0 (-__FP_LONG_MAX - 1)
#define FP_LLOGBNAN (-__FP_LONG_MAX - 1)
#define FP_INT_UPWARD 0
#define FP_INT_DOWNWARD 1
#define FP_INT_TOWARDZERO 2
#define FP_INT_TONEARESTFROMZERO 3
#define FP_INT_TONEAREST 4
#define __SIMD_DECL(function) __CONCAT (__DECL_SIMD_, function)
#define __MATHCALL_VEC(function,suffix,args) __SIMD_DECL (__MATH_PRECNAME (function, suffix)) __MATHCALL (function, suffix, args)
#define __MATHDECL_VEC(type,function,suffix,args) __SIMD_DECL (__MATH_PRECNAME (function, suffix)) __MATHDECL(type, function,suffix, args)
#define __MATHCALL(function,suffix,args) __MATHDECL (_Mdouble_,function,suffix, args)
#define __MATHDECL(type,function,suffix,args) __MATHDECL_1(type, function,suffix, args); __MATHDECL_1(type, __CONCAT(__,function),suffix, args)
#define __MATHCALLX(function,suffix,args,attrib) __MATHDECLX (_Mdouble_,function,suffix, args, attrib)
#define __MATHDECLX(type,function,suffix,args,attrib) __MATHDECL_1(type, function,suffix, args) __attribute__ (attrib); __MATHDECL_1(type, __CONCAT(__,function),suffix, args) __attribute__ (attrib)
#define __MATHDECL_1(type,function,suffix,args) extern type __MATH_PRECNAME(function,suffix) args __THROW
#define _Mdouble_ double
#define __MATH_PRECNAME(name,r) __CONCAT(name,r)
#define __MATH_DECLARING_DOUBLE 1
#define __MATH_DECLARING_FLOATN 0
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ float
#define __MATH_PRECNAME(name,r) name ##f ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 0
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ long double
#define __MATH_PRECNAME(name,r) name ##l ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 0
#define __MATH_DECLARE_LDOUBLE 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ _Float32
#define __MATH_PRECNAME(name,r) name ##f32 ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ _Float64
#define __MATH_PRECNAME(name,r) name ##f64 ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ _Float128
#define __MATH_PRECNAME(name,r) name ##f128 ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ _Float32x
#define __MATH_PRECNAME(name,r) name ##f32x ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#define _Mdouble_ _Float64x
#define __MATH_PRECNAME(name,r) name ##f64x ##r
#define __MATH_DECLARING_DOUBLE 0
#define __MATH_DECLARING_FLOATN 1
#undef _Mdouble_
#undef __MATH_PRECNAME
#undef __MATH_DECLARING_DOUBLE
#undef __MATH_DECLARING_FLOATN
#undef __MATHDECL_1
#undef __MATHDECL
#undef __MATHCALL
#define __MATHCALL_NARROW_ARGS_1 (_Marg_ __x)
#define __MATHCALL_NARROW_ARGS_2 (_Marg_ __x, _Marg_ __y)
#define __MATHCALL_NARROW_ARGS_3 (_Marg_ __x, _Marg_ __y, _Marg_ __z)
#define __MATHCALL_NARROW_NORMAL(func,nargs) extern _Mret_ func __MATHCALL_NARROW_ARGS_ ## nargs __THROW
#define __MATHCALL_NARROW_REDIR(func,redir,nargs) extern _Mret_ __REDIRECT_NTH (func, __MATHCALL_NARROW_ARGS_ ## nargs, redir)
#define __MATHCALL_NARROW(func,redir,nargs) __MATHCALL_NARROW_NORMAL (func, nargs)
#define _Mret_ float
#define _Marg_ double
#define __MATHCALL_NAME(name) f ## name
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ float
#define _Marg_ long double
#define __MATHCALL_NAME(name) f ## name ## l
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ double
#define _Marg_ long double
#define __MATHCALL_NAME(name) d ## name ## l
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32
#define _Marg_ _Float32x
#define __MATHCALL_NAME(name) f32 ## name ## f32x
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32
#define _Marg_ _Float64
#define __MATHCALL_NAME(name) f32 ## name ## f64
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32
#define _Marg_ _Float64x
#define __MATHCALL_NAME(name) f32 ## name ## f64x
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32
#define _Marg_ _Float128
#define __MATHCALL_NAME(name) f32 ## name ## f128
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32x
#define _Marg_ _Float64
#define __MATHCALL_NAME(name) f32x ## name ## f64
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32x
#define _Marg_ _Float64x
#define __MATHCALL_NAME(name) f32x ## name ## f64x
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float32x
#define _Marg_ _Float128
#define __MATHCALL_NAME(name) f32x ## name ## f128
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float64
#define _Marg_ _Float64x
#define __MATHCALL_NAME(name) f64 ## name ## f64x
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float64
#define _Marg_ _Float128
#define __MATHCALL_NAME(name) f64 ## name ## f128
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#define _Mret_ _Float64x
#define _Marg_ _Float128
#define __MATHCALL_NAME(name) f64x ## name ## f128
#undef _Mret_
#undef _Marg_
#undef __MATHCALL_NAME
#undef __MATHCALL_NARROW_ARGS_1
#undef __MATHCALL_NARROW_ARGS_2
#undef __MATHCALL_NARROW_ARGS_3
#undef __MATHCALL_NARROW_NORMAL
#undef __MATHCALL_NARROW_REDIR
#undef __MATHCALL_NARROW
#define __MATH_TG_F32(FUNC,ARGS) _Float32: FUNC ## f ARGS,
#define __MATH_TG_F64X(FUNC,ARGS) _Float64x: FUNC ## l ARGS,
#define __MATH_TG(TG_ARG,FUNC,ARGS) _Generic ((TG_ARG), float: FUNC ## f ARGS, __MATH_TG_F32 (FUNC, ARGS) default: FUNC ARGS, long double: FUNC ## l ARGS, __MATH_TG_F64X (FUNC, ARGS) _Float128: FUNC ## f128 ARGS)
#define FP_NAN 0
#define FP_INFINITE 1
#define FP_ZERO 2
#define FP_SUBNORMAL 3
#define FP_NORMAL 4
#define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
#define signbit(x) __builtin_signbit (x)
#define isfinite(x) __builtin_isfinite (x)
#define isnormal(x) __builtin_isnormal (x)
#define isnan(x) __builtin_isnan (x)
#define isinf(x) __builtin_isinf_sign (x)
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
#define __iscanonicalf(x) ((void) (__typeof (x)) (x), 1)
#define __iscanonical(x) ((void) (__typeof (x)) (x), 1)
#define __iscanonicalf128(x) ((void) (__typeof (x)) (x), 1)
#define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
#define issignaling(x) __MATH_TG ((x), __issignaling, (x))
#define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL)
#define iszero(x) (((__typeof (x)) (x)) == 0)
#define MAXFLOAT 3.40282347e+38F
#define M_E 2.7182818284590452354
#define M_LOG2E 1.4426950408889634074
#define M_LOG10E 0.43429448190325182765
#define M_LN2 0.69314718055994530942
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.78539816339744830962
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.70710678118654752440
#define M_El 2.718281828459045235360287471352662498L
#define M_LOG2El 1.442695040888963407359924681001892137L
#define M_LOG10El 0.434294481903251827651128918916605082L
#define M_LN2l 0.693147180559945309417232121458176568L
#define M_LN10l 2.302585092994045684017991454684364208L
#define M_PIl 3.141592653589793238462643383279502884L
#define M_PI_2l 1.570796326794896619231321691639751442L
#define M_PI_4l 0.785398163397448309615660845819875721L
#define M_1_PIl 0.318309886183790671537767526745028724L
#define M_2_PIl 0.636619772367581343075535053490057448L
#define M_2_SQRTPIl 1.128379167095512573896158903121545172L
#define M_SQRT2l 1.414213562373095048801688724209698079L
#define M_SQRT1_2l 0.707106781186547524400844362104849039L
#define M_Ef32 __f32 (2.718281828459045235360287471352662498)
#define M_LOG2Ef32 __f32 (1.442695040888963407359924681001892137)
#define M_LOG10Ef32 __f32 (0.434294481903251827651128918916605082)
#define M_LN2f32 __f32 (0.693147180559945309417232121458176568)
#define M_LN10f32 __f32 (2.302585092994045684017991454684364208)
#define M_PIf32 __f32 (3.141592653589793238462643383279502884)
#define M_PI_2f32 __f32 (1.570796326794896619231321691639751442)
#define M_PI_4f32 __f32 (0.785398163397448309615660845819875721)
#define M_1_PIf32 __f32 (0.318309886183790671537767526745028724)
#define M_2_PIf32 __f32 (0.636619772367581343075535053490057448)
#define M_2_SQRTPIf32 __f32 (1.128379167095512573896158903121545172)
#define M_SQRT2f32 __f32 (1.414213562373095048801688724209698079)
#define M_SQRT1_2f32 __f32 (0.707106781186547524400844362104849039)
#define M_Ef64 __f64 (2.718281828459045235360287471352662498)
#define M_LOG2Ef64 __f64 (1.442695040888963407359924681001892137)
#define M_LOG10Ef64 __f64 (0.434294481903251827651128918916605082)
#define M_LN2f64 __f64 (0.693147180559945309417232121458176568)
#define M_LN10f64 __f64 (2.302585092994045684017991454684364208)
#define M_PIf64 __f64 (3.141592653589793238462643383279502884)
#define M_PI_2f64 __f64 (1.570796326794896619231321691639751442)
#define M_PI_4f64 __f64 (0.785398163397448309615660845819875721)
#define M_1_PIf64 __f64 (0.318309886183790671537767526745028724)
#define M_2_PIf64 __f64 (0.636619772367581343075535053490057448)
#define M_2_SQRTPIf64 __f64 (1.128379167095512573896158903121545172)
#define M_SQRT2f64 __f64 (1.414213562373095048801688724209698079)
#define M_SQRT1_2f64 __f64 (0.707106781186547524400844362104849039)
#define M_Ef128 __f128 (2.718281828459045235360287471352662498)
#define M_LOG2Ef128 __f128 (1.442695040888963407359924681001892137)
#define M_LOG10Ef128 __f128 (0.434294481903251827651128918916605082)
#define M_LN2f128 __f128 (0.693147180559945309417232121458176568)
#define M_LN10f128 __f128 (2.302585092994045684017991454684364208)
#define M_PIf128 __f128 (3.141592653589793238462643383279502884)
#define M_PI_2f128 __f128 (1.570796326794896619231321691639751442)
#define M_PI_4f128 __f128 (0.785398163397448309615660845819875721)
#define M_1_PIf128 __f128 (0.318309886183790671537767526745028724)
#define M_2_PIf128 __f128 (0.636619772367581343075535053490057448)
#define M_2_SQRTPIf128 __f128 (1.128379167095512573896158903121545172)
#define M_SQRT2f128 __f128 (1.414213562373095048801688724209698079)
#define M_SQRT1_2f128 __f128 (0.707106781186547524400844362104849039)
#define M_Ef32x __f32x (2.718281828459045235360287471352662498)
#define M_LOG2Ef32x __f32x (1.442695040888963407359924681001892137)
#define M_LOG10Ef32x __f32x (0.434294481903251827651128918916605082)
#define M_LN2f32x __f32x (0.693147180559945309417232121458176568)
#define M_LN10f32x __f32x (2.302585092994045684017991454684364208)
#define M_PIf32x __f32x (3.141592653589793238462643383279502884)
#define M_PI_2f32x __f32x (1.570796326794896619231321691639751442)
#define M_PI_4f32x __f32x (0.785398163397448309615660845819875721)
#define M_1_PIf32x __f32x (0.318309886183790671537767526745028724)
#define M_2_PIf32x __f32x (0.636619772367581343075535053490057448)
#define M_2_SQRTPIf32x __f32x (1.128379167095512573896158903121545172)
#define M_SQRT2f32x __f32x (1.414213562373095048801688724209698079)
#define M_SQRT1_2f32x __f32x (0.707106781186547524400844362104849039)
#define M_Ef64x __f64x (2.718281828459045235360287471352662498)
#define M_LOG2Ef64x __f64x (1.442695040888963407359924681001892137)
#define M_LOG10Ef64x __f64x (0.434294481903251827651128918916605082)
#define M_LN2f64x __f64x (0.693147180559945309417232121458176568)
#define M_LN10f64x __f64x (2.302585092994045684017991454684364208)
#define M_PIf64x __f64x (3.141592653589793238462643383279502884)
#define M_PI_2f64x __f64x (1.570796326794896619231321691639751442)
#define M_PI_4f64x __f64x (0.785398163397448309615660845819875721)
#define M_1_PIf64x __f64x (0.318309886183790671537767526745028724)
#define M_2_PIf64x __f64x (0.636619772367581343075535053490057448)
#define M_2_SQRTPIf64x __f64x (1.128379167095512573896158903121545172)
#define M_SQRT2f64x __f64x (1.414213562373095048801688724209698079)
#define M_SQRT1_2f64x __f64x (0.707106781186547524400844362104849039)
#define isgreater(x,y) __builtin_isgreater(x, y)
#define isgreaterequal(x,y) __builtin_isgreaterequal(x, y)
#define isless(x,y) __builtin_isless(x, y)
#define islessequal(x,y) __builtin_islessequal(x, y)
#define islessgreater(x,y) __builtin_islessgreater(x, y)
#define isunordered(x,y) __builtin_isunordered(x, y)
#define __MATH_INLINE __extern_always_inline
#define __MATH_EVAL_FMT2(x,y) ((x) + (y) + 0.0f)
#define iseqsig(x,y) __MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
#define _TIME_H 1
#define __need_size_t
#define __need_NULL
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define _BITS_TIME_H 1
#define CLOCKS_PER_SEC ((__clock_t) 1000000)
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_MONOTONIC_RAW 4
#define CLOCK_REALTIME_COARSE 5
#define CLOCK_MONOTONIC_COARSE 6
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
#define CLOCK_TAI 11
#define TIMER_ABSTIME 1
#define _BITS_TIMEX_H 1
#define ADJ_OFFSET 0x0001
#define ADJ_FREQUENCY 0x0002
#define ADJ_MAXERROR 0x0004
#define ADJ_ESTERROR 0x0008
#define ADJ_STATUS 0x0010
#define ADJ_TIMECONST 0x0020
#define ADJ_TAI 0x0080
#define ADJ_SETOFFSET 0x0100
#define ADJ_MICRO 0x1000
#define ADJ_NANO 0x2000
#define ADJ_TICK 0x4000
#define ADJ_OFFSET_SINGLESHOT 0x8001
#define ADJ_OFFSET_SS_READ 0xa001
#define MOD_OFFSET ADJ_OFFSET
#define MOD_FREQUENCY ADJ_FREQUENCY
#define MOD_MAXERROR ADJ_MAXERROR
#define MOD_ESTERROR ADJ_ESTERROR
#define MOD_STATUS ADJ_STATUS
#define MOD_TIMECONST ADJ_TIMECONST
#define MOD_CLKB ADJ_TICK
#define MOD_CLKA ADJ_OFFSET_SINGLESHOT
#define MOD_TAI ADJ_TAI
#define MOD_MICRO ADJ_MICRO
#define MOD_NANO ADJ_NANO
#define STA_PLL 0x0001
#define STA_PPSFREQ 0x0002
#define STA_PPSTIME 0x0004
#define STA_FLL 0x0008
#define STA_INS 0x0010
#define STA_DEL 0x0020
#define STA_UNSYNC 0x0040
#define STA_FREQHOLD 0x0080
#define STA_PPSSIGNAL 0x0100
#define STA_PPSJITTER 0x0200
#define STA_PPSWANDER 0x0400
#define STA_PPSERROR 0x0800
#define STA_CLOCKERR 0x1000
#define STA_NANO 0x2000
#define STA_MODE 0x4000
#define STA_CLK 0x8000
#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
#define __struct_tm_defined 1
#define __itimerspec_defined 1
#define TIME_UTC 1
#define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#define _SYS_TIME_H 1
#define TIMEVAL_TO_TIMESPEC(tv,ts) { (ts)->tv_sec = (tv)->tv_sec; (ts)->tv_nsec = (tv)->tv_usec * 1000; }
#define TIMESPEC_TO_TIMEVAL(tv,ts) { (tv)->tv_sec = (ts)->tv_sec; (tv)->tv_usec = (ts)->tv_nsec / 1000; }
#define ITIMER_REAL ITIMER_REAL
#define ITIMER_VIRTUAL ITIMER_VIRTUAL
#define ITIMER_PROF ITIMER_PROF
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#define timercmp(a,b,CMP) (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec CMP (b)->tv_usec) : ((a)->tv_sec CMP (b)->tv_sec))
#define timeradd(a,b,result) do { (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; if ((result)->tv_usec >= 1000000) { ++(result)->tv_sec; (result)->tv_usec -= 1000000; } } while (0)
#define timersub(a,b,result) do { (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; if ((result)->tv_usec < 0) { --(result)->tv_sec; (result)->tv_usec += 1000000; } } while (0)
#pragma GCC visibility push(default)
#define HAVE_FINITE 1
#define finite(x) isfinite(x)
#pragma GCC visibility pop
#define RUBY
#define RB_GNUC_EXTENSION __extension__
#define RB_GNUC_EXTENSION_BLOCK(x) __extension__ ({ x; })
#define RUBY_MBCHAR_MAXSIZE INT_MAX
#define FLUSH_REGISTER_WINDOWS ((void)0)
#define RUBY_ABI_H
#define RBIMPL_ANYARGS_H
#define RBIMPL_ATTR_WEAKREF_H
#define RBIMPL_ATTR_WEAKREF(sym) __attribute__((__weakref__(#sym)))
#define RBIMPL_INTERN_CLASS_H
#define RBIMPL_VALUE_H
#define RBIMPL_STATIC_ASSERT_H
#define _ASSERT_H 1
#define __ASSERT_VOID_CAST (void)
#define assert(expr) (__ASSERT_VOID_CAST (0))
#define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
#undef static_assert
#define static_assert _Static_assert
#define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
#define RBIMPL_STATIC_ASSERT(name,expr) RBIMPL_STATIC_ASSERT0(expr, #name ": " #expr)
#define RUBY_BACKWARD2_LIMITS_H
#define _GCC_LIMITS_H_
#define _GCC_NEXT_LIMITS_H
#define _LIBC_LIMITS_H_ 1
#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
#undef __GLIBC_USE_LIB_EXT2
#define __GLIBC_USE_LIB_EXT2 1
#undef __GLIBC_USE_IEC_60559_BFP_EXT
#define __GLIBC_USE_IEC_60559_BFP_EXT 1
#undef __GLIBC_USE_IEC_60559_FUNCS_EXT
#define __GLIBC_USE_IEC_60559_FUNCS_EXT 1
#undef __GLIBC_USE_IEC_60559_TYPES_EXT
#define __GLIBC_USE_IEC_60559_TYPES_EXT 1
#define MB_LEN_MAX 16
#define LLONG_MIN (-LLONG_MAX-1)
#define LLONG_MAX __LONG_LONG_MAX__
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1)
#define CHAR_WIDTH 8
#define SCHAR_WIDTH 8
#define UCHAR_WIDTH 8
#define SHRT_WIDTH 16
#define USHRT_WIDTH 16
#define INT_WIDTH 32
#define UINT_WIDTH 32
#define LONG_WIDTH __WORDSIZE
#define ULONG_WIDTH __WORDSIZE
#define LLONG_WIDTH 64
#define ULLONG_WIDTH 64
#define _BITS_POSIX1_LIM_H 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define _POSIX_AIO_LISTIO_MAX 2
#define _POSIX_AIO_MAX 1
#define _POSIX_ARG_MAX 4096
#define _POSIX_CHILD_MAX 25
#define _POSIX_DELAYTIMER_MAX 32
#define _POSIX_HOST_NAME_MAX 255
#define _POSIX_LINK_MAX 8
#define _POSIX_LOGIN_NAME_MAX 9
#define _POSIX_MAX_CANON 255
#define _POSIX_MAX_INPUT 255
#define _POSIX_MQ_OPEN_MAX 8
#define _POSIX_MQ_PRIO_MAX 32
#define _POSIX_NAME_MAX 14
#define _POSIX_NGROUPS_MAX 8
#define _POSIX_OPEN_MAX 20
#define _POSIX_FD_SETSIZE _POSIX_OPEN_MAX
#define _POSIX_PATH_MAX 256
#define _POSIX_PIPE_BUF 512
#define _POSIX_RE_DUP_MAX 255
#define _POSIX_RTSIG_MAX 8
#define _POSIX_SEM_NSEMS_MAX 256
#define _POSIX_SEM_VALUE_MAX 32767
#define _POSIX_SIGQUEUE_MAX 32
#define _POSIX_SSIZE_MAX 32767
#define _POSIX_STREAM_MAX 8
#define _POSIX_SYMLINK_MAX 255
#define _POSIX_SYMLOOP_MAX 8
#define _POSIX_TIMER_MAX 32
#define _POSIX_TTY_NAME_MAX 9
#define _POSIX_TZNAME_MAX 6
#define _POSIX_QLIMIT 1
#define _POSIX_HIWAT _POSIX_PIPE_BUF
#define _POSIX_UIO_MAXIOV 16
#define _POSIX_CLOCKRES_MIN 20000000
#define __undef_NR_OPEN
#define __undef_LINK_MAX
#define __undef_OPEN_MAX
#define __undef_ARG_MAX
#define _LINUX_LIMITS_H
#define NR_OPEN 1024
#define NGROUPS_MAX 65536
#define ARG_MAX 131072
#define LINK_MAX 127
#define MAX_CANON 255
#define MAX_INPUT 255
#define NAME_MAX 255
#define PATH_MAX 4096
#define PIPE_BUF 4096
#define XATTR_NAME_MAX 255
#define XATTR_SIZE_MAX 65536
#define XATTR_LIST_MAX 65536
#define RTSIG_MAX 32
#undef NR_OPEN
#undef __undef_NR_OPEN
#undef LINK_MAX
#undef __undef_LINK_MAX
#undef OPEN_MAX
#undef __undef_OPEN_MAX
#undef ARG_MAX
#undef __undef_ARG_MAX
#define _POSIX_THREAD_KEYS_MAX 128
#define PTHREAD_KEYS_MAX 1024
#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
#define _POSIX_THREAD_THREADS_MAX 64
#undef PTHREAD_THREADS_MAX
#define AIO_PRIO_DELTA_MAX 20
#define PTHREAD_STACK_MIN 16384
#define DELAYTIMER_MAX 2147483647
#define TTY_NAME_MAX 32
#define LOGIN_NAME_MAX 256
#define HOST_NAME_MAX 64
#define MQ_PRIO_MAX 32768
#define SEM_VALUE_MAX (2147483647)
#define SSIZE_MAX LONG_MAX
#define _BITS_POSIX2_LIM_H 1
#define _POSIX2_BC_BASE_MAX 99
#define _POSIX2_BC_DIM_MAX 2048
#define _POSIX2_BC_SCALE_MAX 99
#define _POSIX2_BC_STRING_MAX 1000
#define _POSIX2_COLL_WEIGHTS_MAX 2
#define _POSIX2_EXPR_NEST_MAX 32
#define _POSIX2_LINE_MAX 2048
#define _POSIX2_RE_DUP_MAX 255
#define _POSIX2_CHARCLASS_NAME_MAX 14
#define BC_BASE_MAX _POSIX2_BC_BASE_MAX
#define BC_DIM_MAX _POSIX2_BC_DIM_MAX
#define BC_SCALE_MAX _POSIX2_BC_SCALE_MAX
#define BC_STRING_MAX _POSIX2_BC_STRING_MAX
#define COLL_WEIGHTS_MAX 255
#define EXPR_NEST_MAX _POSIX2_EXPR_NEST_MAX
#define LINE_MAX _POSIX2_LINE_MAX
#define CHARCLASS_NAME_MAX 2048
#define RE_DUP_MAX (0x7fff)
#define _XOPEN_LIM_H 1
#define _XOPEN_IOV_MAX _POSIX_UIO_MAXIOV
#define _BITS_UIO_LIM_H 1
#define __IOV_MAX 1024
#define IOV_MAX __IOV_MAX
#define NL_ARGMAX _POSIX_ARG_MAX
#define NL_LANGMAX _POSIX2_LINE_MAX
#define NL_MSGMAX INT_MAX
#define NL_NMAX INT_MAX
#define NL_SETMAX INT_MAX
#define NL_TEXTMAX INT_MAX
#define NZERO 20
#define WORD_BIT 32
#define LONG_BIT 64
#undef _GCC_NEXT_LIMITS_H
#define _LIMITS_H___
#undef CHAR_BIT
#define CHAR_BIT __CHAR_BIT__
#undef SCHAR_MIN
#define SCHAR_MIN (-SCHAR_MAX - 1)
#undef SCHAR_MAX
#define SCHAR_MAX __SCHAR_MAX__
#undef UCHAR_MAX
#define UCHAR_MAX (SCHAR_MAX * 2 + 1)
#undef CHAR_MIN
#define CHAR_MIN SCHAR_MIN
#undef CHAR_MAX
#define CHAR_MAX SCHAR_MAX
#undef SHRT_MIN
#define SHRT_MIN (-SHRT_MAX - 1)
#undef SHRT_MAX
#define SHRT_MAX __SHRT_MAX__
#undef USHRT_MAX
#define USHRT_MAX (SHRT_MAX * 2 + 1)
#undef INT_MIN
#define INT_MIN (-INT_MAX - 1)
#undef INT_MAX
#define INT_MAX __INT_MAX__
#undef UINT_MAX
#define UINT_MAX (INT_MAX * 2U + 1U)
#undef LONG_MIN
#define LONG_MIN (-LONG_MAX - 1L)
#undef LONG_MAX
#define LONG_MAX __LONG_MAX__
#undef ULONG_MAX
#define ULONG_MAX (LONG_MAX * 2UL + 1UL)
#undef LLONG_MIN
#define LLONG_MIN (-LLONG_MAX - 1LL)
#undef LLONG_MAX
#define LLONG_MAX __LONG_LONG_MAX__
#undef ULLONG_MAX
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
#undef LONG_LONG_MIN
#define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL)
#undef LONG_LONG_MAX
#define LONG_LONG_MAX __LONG_LONG_MAX__
#undef ULONG_LONG_MAX
#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL)
#define SIGNED_VALUE long
#define SIZEOF_VALUE SIZEOF_LONG
#define PRI_VALUE_PREFIX "l"
#define RBIMPL_VALUE_NULL 0UL
#define RBIMPL_VALUE_ONE 1UL
#define RBIMPL_VALUE_FULL ULONG_MAX
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_VM_H
#pragma GCC visibility push(default)
#define HAVE_RB_DEFINE_ALLOC_FUNC 1
#pragma GCC visibility pop
#define RBIMPL_METHOD_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_CFUNC_IS_rb_f_notimplement(f) __builtin_types_compatible_p( __typeof__(f), __typeof__(rb_f_notimplement))
#define RBIMPL_ANYARGS_DISPATCH(expr,truthy,falsy) __builtin_choose_expr( __builtin_choose_expr( __builtin_constant_p(expr), (expr), 0), (truthy), (falsy))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_singleton_method_m2, rb_define_singleton_method_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_singleton_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_singleton_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_singleton_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_singleton_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_singleton_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_singleton_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_singleton_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_singleton_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_singleton_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_singleton_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_singleton_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_singleton_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_singleton_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_singleton_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_singleton_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_singleton_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_singleton_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_protected_method_m2, rb_define_protected_method_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_protected_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_protected_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_protected_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_protected_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_protected_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_protected_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_protected_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_protected_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_protected_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_protected_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_protected_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_protected_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_protected_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_protected_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_protected_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_protected_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_protected_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_private_method_m2, rb_define_private_method_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_private_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_private_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_private_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_private_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_private_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_private_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_private_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_private_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_private_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_private_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_private_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_private_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_private_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_private_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_private_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_private_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_private_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_module_function_m2, rb_define_module_function_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_module_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_module_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_module_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_module_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_module_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_module_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_module_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_module_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_module_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_module_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_module_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_module_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_module_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_module_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_module_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_module_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_module_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_global_function_m2, rb_define_global_function_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_global_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_global_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_global_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_global_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_global_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_global_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_global_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_global_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_global_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_global_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_global_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_global_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_global_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_global_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_global_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_global_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_global_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_id_m2, rb_define_method_id_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_id_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_id_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_id_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_id_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_id_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_id_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_id_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_id_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_id_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_id_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_id_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_id_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_id_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_id_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_id_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_id_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_id_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_m2, rb_define_method_m3)
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
#define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n,f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
#define RBIMPL_ANYARGS_ATTRSET(sym) RBIMPL_ATTR_MAYBE_UNUSED() RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_WEAKREF(sym)
#define RBIMPL_ANYARGS_DECL(sym,...) RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _notimpl(__VA_ARGS__, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m2(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _01(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _02(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _03(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _04(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _05(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _06(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _07(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _08(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _09(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _10(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _11(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _12(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _13(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _14(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _15(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
#define rb_define_method(klass,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
#define rb_define_method_id(klass,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method_id((arity), (func))((klass), (mid), (func), (arity))
#define rb_define_singleton_method(obj,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method((arity), (func))((obj), (mid), (func), (arity))
#define rb_define_protected_method(klass,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method((arity), (func))((klass), (mid), (func), (arity))
#define rb_define_private_method(klass,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_private_method((arity), (func))((klass), (mid), (func), (arity))
#define rb_define_module_function(mod,mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_module_function((arity), (func))((mod), (mid), (func), (arity))
#define rb_define_global_function(mid,func,arity) RBIMPL_ANYARGS_DISPATCH_rb_define_global_function((arity), (func))((mid), (func), (arity))
#define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
#define RBIMPL_ARITHMETIC_H
#define RBIMPL_ARITHMETIC_CHAR_H
#define RBIMPL_ARITHMETIC_INT_H
#define RBIMPL_ARITHMETIC_FIXNUM_H
#define FIXABLE RB_FIXABLE
#define FIXNUM_MAX RUBY_FIXNUM_MAX
#define FIXNUM_MIN RUBY_FIXNUM_MIN
#define NEGFIXABLE RB_NEGFIXABLE
#define POSFIXABLE RB_POSFIXABLE
#define RB_POSFIXABLE(_) ((_) < RUBY_FIXNUM_MAX + 1)
#define RB_NEGFIXABLE(_) ((_) >= RUBY_FIXNUM_MIN)
#define RB_FIXABLE(_) (RB_POSFIXABLE(_) && RB_NEGFIXABLE(_))
#define RUBY_FIXNUM_MAX (LONG_MAX / 2)
#define RUBY_FIXNUM_MIN (LONG_MIN / 2)
#define RBIMPL_ARITHMETIC_INTPTR_T_H
#define rb_int_new rb_int2inum
#define rb_uint_new rb_uint2inum
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ARITHMETIC_LONG_H
#define RBIMPL_ATTR_ARTIFICIAL_H
#define RBIMPL_ATTR_ARTIFICIAL() __attribute__((__artificial__))
#define RBIMPL_ATTR_CONSTEXPR_H
#define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
#define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
#define RBIMPL_ATTR_CONSTEXPR(_)
#define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) RBIMPL_ATTR_CONSTEXPR(_)
#define RBIMPL_SPECIAL_CONSTS_H
#define RBIMPL_ATTR_ENUM_EXTENSIBILITY_H
#define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_)
#define USE_FLONUM 1
#define RTEST RB_TEST
#define FIXNUM_P RB_FIXNUM_P
#define IMMEDIATE_P RB_IMMEDIATE_P
#define NIL_P RB_NIL_P
#define SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define STATIC_SYM_P RB_STATIC_SYM_P
#define Qfalse RUBY_Qfalse
#define Qnil RUBY_Qnil
#define Qtrue RUBY_Qtrue
#define Qundef RUBY_Qundef
#define FIXNUM_FLAG RUBY_FIXNUM_FLAG
#define FLONUM_FLAG RUBY_FLONUM_FLAG
#define FLONUM_MASK RUBY_FLONUM_MASK
#define FLONUM_P RB_FLONUM_P
#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
#define SYMBOL_FLAG RUBY_SYMBOL_FLAG
#define RB_FIXNUM_P RB_FIXNUM_P
#define RB_FLONUM_P RB_FLONUM_P
#define RB_IMMEDIATE_P RB_IMMEDIATE_P
#define RB_NIL_P RB_NIL_P
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define RB_STATIC_SYM_P RB_STATIC_SYM_P
#define RB_TEST RB_TEST
#define RB_UNDEF_P RB_UNDEF_P
#define RB_NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
#define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
#define RUBY_Qtrue RBIMPL_CAST((VALUE)RUBY_Qtrue)
#define RUBY_Qnil RBIMPL_CAST((VALUE)RUBY_Qnil)
#define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
#define FIX2LONG RB_FIX2LONG
#define FIX2ULONG RB_FIX2ULONG
#define INT2FIX RB_INT2FIX
#define LONG2FIX RB_INT2FIX
#define LONG2NUM RB_LONG2NUM
#define NUM2LONG RB_NUM2LONG
#define NUM2ULONG RB_NUM2ULONG
#define RB_FIX2LONG rb_fix2long
#define RB_FIX2ULONG rb_fix2ulong
#define RB_LONG2FIX RB_INT2FIX
#define RB_LONG2NUM rb_long2num_inline
#define RB_NUM2LONG rb_num2long_inline
#define RB_NUM2ULONG rb_num2ulong_inline
#define RB_ULONG2NUM rb_ulong2num_inline
#define ULONG2NUM RB_ULONG2NUM
#define rb_fix_new RB_INT2FIX
#define rb_long2int rb_long2int_inline
#define RB_INT2FIX RB_INT2FIX
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#undef INT2FIX
#define INT2FIX(i) __builtin_choose_expr( __builtin_constant_p(i), RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG, RB_INT2FIX(i))
#define RB_INT2NUM rb_int2num_inline
#define RB_NUM2INT rb_num2int_inline
#define RB_UINT2NUM rb_uint2num_inline
#define FIX2INT RB_FIX2INT
#define FIX2UINT RB_FIX2UINT
#define INT2NUM RB_INT2NUM
#define NUM2INT RB_NUM2INT
#define NUM2UINT RB_NUM2UINT
#define UINT2NUM RB_UINT2NUM
#define RB_FIX2INT RB_FIX2INT
#define RB_NUM2UINT RB_NUM2UINT
#define RB_FIX2UINT RB_FIX2UINT
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#pragma GCC diagnostic pop
#define RBIMPL_RSTRING_H
#define RBIMPL_RBASIC_H
#define RBIMPL_ATTR_NOALIAS_H
#define RBIMPL_ATTR_NOALIAS()
#define RBASIC(obj) RBIMPL_CAST((struct RBasic *)(obj))
#define RBASIC_CLASS RBASIC_CLASS
#define RBIMPL_RVALUE_EMBED_LEN_MAX 3
#define RVALUE_EMBED_LEN_MAX RVALUE_EMBED_LEN_MAX
#define RBIMPL_EMBED_LEN_MAX_OF(T) RBIMPL_CAST((int)(sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]) / (sizeof(T))))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_FL_TYPE_H
#define RBIMPL_ATTR_FLAG_ENUM_H
#define RBIMPL_ATTR_FLAG_ENUM()
#define RBIMPL_VALUE_TYPE_H
#define RBIMPL_CONSTANT_P_H
#define RBIMPL_CONSTANT_P(expr) __builtin_constant_p(expr)
#define RBIMPL_ERROR_H
#define RB_IO_WAIT_READABLE RB_IO_WAIT_READABLE
#define RB_IO_WAIT_WRITABLE RB_IO_WAIT_WRITABLE
#pragma GCC visibility push(default)
#define ruby_verbose (*rb_ruby_verbose_ptr())
#define ruby_debug (*rb_ruby_debug_ptr())
#pragma GCC visibility pop
#define T_ARRAY RUBY_T_ARRAY
#define T_BIGNUM RUBY_T_BIGNUM
#define T_CLASS RUBY_T_CLASS
#define T_COMPLEX RUBY_T_COMPLEX
#define T_DATA RUBY_T_DATA
#define T_FALSE RUBY_T_FALSE
#define T_FILE RUBY_T_FILE
#define T_FIXNUM RUBY_T_FIXNUM
#define T_FLOAT RUBY_T_FLOAT
#define T_HASH RUBY_T_HASH
#define T_ICLASS RUBY_T_ICLASS
#define T_IMEMO RUBY_T_IMEMO
#define T_MASK RUBY_T_MASK
#define T_MATCH RUBY_T_MATCH
#define T_MODULE RUBY_T_MODULE
#define T_MOVED RUBY_T_MOVED
#define T_NIL RUBY_T_NIL
#define T_NODE RUBY_T_NODE
#define T_NONE RUBY_T_NONE
#define T_OBJECT RUBY_T_OBJECT
#define T_RATIONAL RUBY_T_RATIONAL
#define T_REGEXP RUBY_T_REGEXP
#define T_STRING RUBY_T_STRING
#define T_STRUCT RUBY_T_STRUCT
#define T_SYMBOL RUBY_T_SYMBOL
#define T_TRUE RUBY_T_TRUE
#define T_UNDEF RUBY_T_UNDEF
#define T_ZOMBIE RUBY_T_ZOMBIE
#define BUILTIN_TYPE RB_BUILTIN_TYPE
#define DYNAMIC_SYM_P RB_DYNAMIC_SYM_P
#define RB_INTEGER_TYPE_P rb_integer_type_p
#define SYMBOL_P RB_SYMBOL_P
#define rb_type_p RB_TYPE_P
#define RB_BUILTIN_TYPE RB_BUILTIN_TYPE
#define RB_DYNAMIC_SYM_P RB_DYNAMIC_SYM_P
#define RB_FLOAT_TYPE_P RB_FLOAT_TYPE_P
#define RB_SYMBOL_P RB_SYMBOL_P
#define RB_TYPE_P RB_TYPE_P
#define Check_Type Check_Type
#define RBIMPL_ASSERT_TYPE(v,t) RBIMPL_ASSERT_OR_ASSUME(RB_TYPE_P((v), (t)))
#define TYPE(_) RBIMPL_CAST((int)rb_type(_))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_HAVE_ENUM_ATTRIBUTE 1
#define RBIMPL_WIDER_ENUM 1
#define FL_SINGLETON RBIMPL_CAST((VALUE)RUBY_FL_SINGLETON)
#define FL_WB_PROTECTED RBIMPL_CAST((VALUE)RUBY_FL_WB_PROTECTED)
#define FL_PROMOTED0 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED0)
#define FL_PROMOTED1 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED1)
#define FL_FINALIZE RBIMPL_CAST((VALUE)RUBY_FL_FINALIZE)
#define FL_TAINT RBIMPL_CAST((VALUE)RUBY_FL_TAINT)
#define FL_SHAREABLE RBIMPL_CAST((VALUE)RUBY_FL_SHAREABLE)
#define FL_UNTRUSTED RBIMPL_CAST((VALUE)RUBY_FL_UNTRUSTED)
#define FL_SEEN_OBJ_ID RBIMPL_CAST((VALUE)RUBY_FL_SEEN_OBJ_ID)
#define FL_EXIVAR RBIMPL_CAST((VALUE)RUBY_FL_EXIVAR)
#define FL_FREEZE RBIMPL_CAST((VALUE)RUBY_FL_FREEZE)
#define FL_USHIFT RBIMPL_CAST((VALUE)RUBY_FL_USHIFT)
#define FL_USER0 RBIMPL_CAST((VALUE)RUBY_FL_USER0)
#define FL_USER1 RBIMPL_CAST((VALUE)RUBY_FL_USER1)
#define FL_USER2 RBIMPL_CAST((VALUE)RUBY_FL_USER2)
#define FL_USER3 RBIMPL_CAST((VALUE)RUBY_FL_USER3)
#define FL_USER4 RBIMPL_CAST((VALUE)RUBY_FL_USER4)
#define FL_USER5 RBIMPL_CAST((VALUE)RUBY_FL_USER5)
#define FL_USER6 RBIMPL_CAST((VALUE)RUBY_FL_USER6)
#define FL_USER7 RBIMPL_CAST((VALUE)RUBY_FL_USER7)
#define FL_USER8 RBIMPL_CAST((VALUE)RUBY_FL_USER8)
#define FL_USER9 RBIMPL_CAST((VALUE)RUBY_FL_USER9)
#define FL_USER10 RBIMPL_CAST((VALUE)RUBY_FL_USER10)
#define FL_USER11 RBIMPL_CAST((VALUE)RUBY_FL_USER11)
#define FL_USER12 RBIMPL_CAST((VALUE)RUBY_FL_USER12)
#define FL_USER13 RBIMPL_CAST((VALUE)RUBY_FL_USER13)
#define FL_USER14 RBIMPL_CAST((VALUE)RUBY_FL_USER14)
#define FL_USER15 RBIMPL_CAST((VALUE)RUBY_FL_USER15)
#define FL_USER16 RBIMPL_CAST((VALUE)RUBY_FL_USER16)
#define FL_USER17 RBIMPL_CAST((VALUE)RUBY_FL_USER17)
#define FL_USER18 RBIMPL_CAST((VALUE)RUBY_FL_USER18)
#define FL_USER19 RBIMPL_CAST((VALUE)(unsigned int)RUBY_FL_USER19)
#define ELTS_SHARED RUBY_ELTS_SHARED
#define RB_OBJ_FREEZE rb_obj_freeze_inline
#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED
#define RB_FL_ABLE RB_FL_ABLE
#define RB_FL_ALL RB_FL_ALL
#define RB_FL_ALL_RAW RB_FL_ALL_RAW
#define RB_FL_ANY RB_FL_ANY
#define RB_FL_ANY_RAW RB_FL_ANY_RAW
#define RB_FL_REVERSE RB_FL_REVERSE
#define RB_FL_REVERSE_RAW RB_FL_REVERSE_RAW
#define RB_FL_SET RB_FL_SET
#define RB_FL_SET_RAW RB_FL_SET_RAW
#define RB_FL_TEST RB_FL_TEST
#define RB_FL_TEST_RAW RB_FL_TEST_RAW
#define RB_FL_UNSET RB_FL_UNSET
#define RB_FL_UNSET_RAW RB_FL_UNSET_RAW
#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
#define RB_OBJ_FROZEN RB_OBJ_FROZEN
#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
#define RB_OBJ_INFECT RB_OBJ_INFECT
#define RB_OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
#define RB_OBJ_TAINT RB_OBJ_TAINT
#define RB_OBJ_TAINTABLE RB_OBJ_TAINTABLE
#define RB_OBJ_TAINTED RB_OBJ_TAINTED
#define RB_OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
#define RB_OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
#define RB_OBJ_UNTRUST RB_OBJ_TAINT
#define RB_OBJ_UNTRUSTED RB_OBJ_TAINTED
#define FL_ABLE RB_FL_ABLE
#define FL_ALL RB_FL_ALL
#define FL_ALL_RAW RB_FL_ALL_RAW
#define FL_ANY RB_FL_ANY
#define FL_ANY_RAW RB_FL_ANY_RAW
#define FL_REVERSE RB_FL_REVERSE
#define FL_REVERSE_RAW RB_FL_REVERSE_RAW
#define FL_SET RB_FL_SET
#define FL_SET_RAW RB_FL_SET_RAW
#define FL_TEST RB_FL_TEST
#define FL_TEST_RAW RB_FL_TEST_RAW
#define FL_UNSET RB_FL_UNSET
#define FL_UNSET_RAW RB_FL_UNSET_RAW
#define OBJ_FREEZE RB_OBJ_FREEZE
#define OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
#define OBJ_FROZEN RB_OBJ_FROZEN
#define OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
#define OBJ_INFECT RB_OBJ_INFECT
#define OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
#define OBJ_TAINT RB_OBJ_TAINT
#define OBJ_TAINTABLE RB_OBJ_TAINTABLE
#define OBJ_TAINTED RB_OBJ_TAINTED
#define OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
#define OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
#define OBJ_UNTRUST RB_OBJ_UNTRUST
#define OBJ_UNTRUSTED RB_OBJ_UNTRUSTED
#define RBIMPL_FL_USER_N(n) RUBY_FL_USER ##n = (1<<(RUBY_FL_USHIFT+n))
#undef RBIMPL_FL_USER_N
#undef RBIMPL_WIDER_ENUM
#undef RBIMPL_HAVE_ENUM_ATTRIBUTE
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RSTRING(obj) RBIMPL_CAST((struct RString *)(obj))
#define RSTRING_NOEMBED RSTRING_NOEMBED
#define RSTRING_FSTR RSTRING_FSTR
#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
#define RSTRING_LEN RSTRING_LEN
#define RSTRING_LENINT RSTRING_LENINT
#define RSTRING_PTR RSTRING_PTR
#define RSTRING_END RSTRING_END
#define StringValue(v) rb_string_value(&(v))
#define StringValuePtr(v) rb_string_value_ptr(&(v))
#define StringValueCStr(v) rb_string_value_cstr(&(v))
#define SafeStringValue(v) StringValue(v)
#define ExportStringValue(v) do { StringValue(v); (v) = rb_str_export(v); } while (0)
#pragma GCC visibility push(default)
#define Check_SafeStr(v) rb_check_safe_str(RBIMPL_CAST((VALUE)(v)))
#pragma GCC visibility pop
#pragma GCC diagnostic push
#pragma GCC diagnostic pop
#define RSTRING_GETMEM(str,ptrvar,lenvar) __extension__ ({ struct RString rbimpl_str = rbimpl_rstring_getmem(str); (ptrvar) = rbimpl_str.as.heap.ptr; (lenvar) = rbimpl_str.as.heap.len; })
#define RB_NUM2CHR rb_num2char_inline
#define NUM2CHR RB_NUM2CHR
#define CHR2FIX RB_CHR2FIX
#define RB_CHR2FIX RB_CHR2FIX
#define RBIMPL_ARITHMETIC_DOUBLE_H
#define NUM2DBL rb_num2dbl
#define RFLOAT_VALUE rb_float_value
#define DBL2NUM rb_float_new
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ARITHMETIC_GID_T_H
#define RBIMPL_ARITHMETIC_LONG_LONG_H
#define RB_LL2NUM rb_ll2num_inline
#define RB_ULL2NUM rb_ull2num_inline
#define LL2NUM RB_LL2NUM
#define ULL2NUM RB_ULL2NUM
#define RB_NUM2LL rb_num2ll_inline
#define RB_NUM2ULL rb_num2ull_inline
#define NUM2LL RB_NUM2LL
#define NUM2ULL RB_NUM2ULL
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ARITHMETIC_MODE_T_H
#define RBIMPL_ARITHMETIC_OFF_T_H
#define RBIMPL_ARITHMETIC_PID_T_H
#define RBIMPL_ARITHMETIC_SHORT_H
#define RB_NUM2SHORT rb_num2short_inline
#define RB_NUM2USHORT rb_num2ushort
#define NUM2SHORT RB_NUM2SHORT
#define NUM2USHORT RB_NUM2USHORT
#define USHORT2NUM RB_INT2FIX
#define RB_FIX2SHORT rb_fix2short
#define FIX2SHORT RB_FIX2SHORT
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ARITHMETIC_SIZE_T_H
#define RB_SIZE2NUM RB_ULL2NUM
#define RB_SSIZE2NUM RB_LL2NUM
#define RB_NUM2SIZE RB_NUM2ULL
#define RB_NUM2SSIZE RB_NUM2LL
#define NUM2SIZET RB_NUM2SIZE
#define SIZET2NUM RB_SIZE2NUM
#define NUM2SSIZET RB_NUM2SSIZE
#define SSIZET2NUM RB_SSIZE2NUM
#define RBIMPL_ARITHMERIC_ST_DATA_T_H
#define RUBY_ST_H 1
#pragma GCC visibility push(default)
#define ST_DATA_T_DEFINED
#define MAX_ST_INDEX_VAL (~(st_index_t) 0)
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)
#define ST_DATA_COMPATIBLE_P(type) __builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
#define st_table_size rb_st_table_size
#define st_init_table rb_st_init_table
#define st_init_table_with_size rb_st_init_table_with_size
#define st_init_numtable rb_st_init_numtable
#define st_init_numtable_with_size rb_st_init_numtable_with_size
#define st_init_strtable rb_st_init_strtable
#define st_init_strtable_with_size rb_st_init_strtable_with_size
#define st_init_strcasetable rb_st_init_strcasetable
#define st_init_strcasetable_with_size rb_st_init_strcasetable_with_size
#define st_delete rb_st_delete
#define st_delete_safe rb_st_delete_safe
#define st_shift rb_st_shift
#define st_insert rb_st_insert
#define st_insert2 rb_st_insert2
#define st_lookup rb_st_lookup
#define st_get_key rb_st_get_key
#define st_update rb_st_update
#define st_foreach_with_replace rb_st_foreach_with_replace
#define st_foreach rb_st_foreach
#define st_foreach_check rb_st_foreach_check
#define st_keys rb_st_keys
#define st_keys_check rb_st_keys_check
#define st_values rb_st_values
#define st_values_check rb_st_values_check
#define st_add_direct rb_st_add_direct
#define st_free_table rb_st_free_table
#define st_cleanup_safe rb_st_cleanup_safe
#define st_clear rb_st_clear
#define st_copy rb_st_copy
#define st_numcmp rb_st_numcmp
#define st_numhash rb_st_numhash
#define st_locale_insensitive_strcasecmp rb_st_locale_insensitive_strcasecmp
#define st_locale_insensitive_strncasecmp rb_st_locale_insensitive_strncasecmp
#define st_strcasecmp rb_st_locale_insensitive_strcasecmp
#define st_strncasecmp rb_st_locale_insensitive_strncasecmp
#define st_memsize rb_st_memsize
#define st_hash rb_st_hash
#define st_hash_uint32 rb_st_hash_uint32
#define st_hash_uint rb_st_hash_uint
#define st_hash_end rb_st_hash_end
#define st_hash_start(h) ((st_index_t)(h))
#pragma GCC visibility pop
#define ST2FIX RB_ST2FIX
#define RB_ST2FIX RB_ST2FIX
#define RBIMPL_ARITHMETIC_UID_T_H
#define RBIMPL_CORE_H
#define RBIMPL_RARRAY_H
#define RBIMPL_RGENGC_H
#undef USE_RGENGC
#define USE_RGENGC 1
#define USE_RINCGC 1
#define USE_RGENGC_LOGGING_WB_UNPROTECT 0
#define RGENGC_WB_PROTECTED_ARRAY 1
#define RGENGC_WB_PROTECTED_HASH 1
#define RGENGC_WB_PROTECTED_STRUCT 1
#define RGENGC_WB_PROTECTED_STRING 1
#define RGENGC_WB_PROTECTED_OBJECT 1
#define RGENGC_WB_PROTECTED_REGEXP 1
#define RGENGC_WB_PROTECTED_CLASS 1
#define RGENGC_WB_PROTECTED_FLOAT 1
#define RGENGC_WB_PROTECTED_COMPLEX 1
#define RGENGC_WB_PROTECTED_RATIONAL 1
#define RGENGC_WB_PROTECTED_BIGNUM 1
#define RGENGC_WB_PROTECTED_NODE_CREF 1
#define RB_OBJ_WRITE(old,slot,young) RBIMPL_CAST(rb_obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))
#define RB_OBJ_WRITTEN(old,oldv,young) RBIMPL_CAST(rb_obj_written((VALUE)(old), (VALUE)(oldv), (VALUE)(young), __FILE__, __LINE__))
#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
#define OBJ_PROMOTED RB_OBJ_PROMOTED
#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT
#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
#define RB_OBJ_WB_UNPROTECT_FOR(type,obj) (RGENGC_WB_PROTECTED_ ##type ? OBJ_WB_UNPROTECT(obj) : obj)
#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
#define RB_OBJ_PROMOTED RB_OBJ_PROMOTED
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define USE_TRANSIENT_HEAP 1
#define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
#define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
#define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
#define RARRAY_LEN rb_array_len
#define RARRAY_CONST_PTR rb_array_const_ptr
#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient
#define FIX_CONST_VALUE_PTR(x) (x)
#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
#define RARRAY_LENINT RARRAY_LENINT
#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
#define RARRAY_ASET RARRAY_ASET
#define RARRAY_PTR RARRAY_PTR
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_RARRAY_STMT(flag,ary,var,expr) do { RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); const VALUE rbimpl_ary = (ary); VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); expr; rb_array_ptr_use_end(rbimpl_ary, (flag)); } while (0)
#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
#define RARRAY_PTR_USE(ary,ptr_name,expr) RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
#define RARRAY_PTR_USE_TRANSIENT(ary,ptr_name,expr) RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
#define RARRAY_AREF(a,i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
#define RBIMPL_RBIGNUM_H
#define RBIGNUM_SIGN rb_big_sign
#define RBIGNUM_POSITIVE_P RBIGNUM_POSITIVE_P
#define RBIGNUM_NEGATIVE_P RBIGNUM_NEGATIVE_P
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_RCLASS_H
#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
#define RCLASS(obj) RBIMPL_CAST((struct RClass *)(obj))
#define RMODULE RCLASS
#define RCLASS_SUPER rb_class_get_superclass
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_RDATA_H
#define RUBY_UNTYPED_DATA_WARNING 1
#define RBIMPL_DATA_FUNC(f) RBIMPL_CAST((void (*)(void *))(f))
#define RBIMPL_ATTRSET_UNTYPED_DATA_FUNC() RBIMPL_ATTR_WARNING(("untyped Data is unsafe; use TypedData instead")) RBIMPL_ATTR_DEPRECATED(("by TypedData"))
#define RBIMPL_MACRO_SELECT(x,y) x ## y
#define RUBY_MACRO_SELECT(x,y) RBIMPL_MACRO_SELECT(x, y)
#define RDATA(obj) RBIMPL_CAST((struct RData *)(obj))
#define DATA_PTR(obj) RDATA(obj)->data
#define RUBY_DEFAULT_FREE RBIMPL_DATA_FUNC(-1)
#define RUBY_NEVER_FREE RBIMPL_DATA_FUNC(0)
#define RUBY_UNTYPED_DATA_FUNC(f) f RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define Data_Wrap_Struct(klass,mark,free,sval) rb_data_object_wrap( (klass), (sval), RBIMPL_DATA_FUNC(mark), RBIMPL_DATA_FUNC(free))
#define Data_Make_Struct0(result,klass,type,size,mark,free,sval) VALUE result = rb_data_object_zalloc( (klass), (size), RBIMPL_DATA_FUNC(mark), RBIMPL_DATA_FUNC(free)); (sval) = RBIMPL_CAST((type *)DATA_PTR(result)); RBIMPL_CAST( (void)(sval))
#define Data_Make_Struct(klass,type,mark,free,sval) RB_GNUC_EXTENSION({ Data_Make_Struct0( data_struct_obj, klass, type, sizeof(type), mark, free, sval); data_struct_obj; })
#define Data_Get_Struct(obj,type,sval) ((sval) = RBIMPL_CAST((type*)rb_data_object_get(obj)))
#define rb_data_object_wrap_warning(klass,ptr,mark,free) RB_GNUC_EXTENSION( __builtin_choose_expr( __builtin_constant_p(klass) && !(klass), rb_data_object_wrap(klass, ptr, mark, free), (rb_data_object_wrap_warning)(klass, ptr, mark, free)))
#define rb_data_object_wrap_0 rb_data_object_wrap
#define rb_data_object_wrap_1 rb_data_object_wrap_warning
#define rb_data_object_wrap_2 rb_data_object_wrap_
#define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_get_0 rb_data_object_get
#define rb_data_object_get_1 rb_data_object_get_warning
#define rb_data_object_get_2 rb_data_object_get_
#define rb_data_object_get RUBY_MACRO_SELECT(rb_data_object_get_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_make_0 rb_data_object_make
#define rb_data_object_make_1 rb_data_object_make_warning
#define rb_data_object_make_2 rb_data_object_make_
#define rb_data_object_make RUBY_MACRO_SELECT(rb_data_object_make_2, RUBY_UNTYPED_DATA_WARNING)
#define RBIMPL_RFILE_H
#define RFILE(obj) RBIMPL_CAST((struct RFile *)(obj))
#define RBIMPL_RHASH_H
#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)
#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
#define RHASH_IFNONE(h) rb_hash_ifnone(h)
#define RHASH_SIZE(h) rb_hash_size_num(h)
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
#define RHASH_SET_IFNONE(h,ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_ROBJECT_H
#define ROBJECT(obj) RBIMPL_CAST((struct RObject *)(obj))
#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
#define ROBJECT_EMBED ROBJECT_EMBED
#define ROBJECT_IV_CAPACITY ROBJECT_IV_CAPACITY
#define ROBJECT_IVPTR ROBJECT_IVPTR
#define RBIMPL_RREGEXP_H
#define RREGEXP(obj) RBIMPL_CAST((struct RRegexp *)(obj))
#define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr)
#define RREGEXP_SRC RREGEXP_SRC
#define RREGEXP_SRC_PTR RREGEXP_SRC_PTR
#define RREGEXP_SRC_LEN RREGEXP_SRC_LEN
#define RREGEXP_SRC_END RREGEXP_SRC_END
#define RBIMPL_RSTRUCT_H
#define RSTRUCT_PTR(st) rb_struct_ptr(st)
#define RSTRUCT_LEN RSTRUCT_LEN
#define RSTRUCT_SET RSTRUCT_SET
#define RSTRUCT_GET RSTRUCT_GET
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_RTYPEDDATA_H
#define HAVE_TYPE_RB_DATA_TYPE_T 1
#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
#define HAVE_RB_DATA_TYPE_T_PARENT 1
#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
#define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj))
#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
#define Check_TypedStruct(v,t) rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))
#define RTYPEDDATA_P RTYPEDDATA_P
#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define TypedData_Wrap_Struct(klass,data_type,sval) rb_data_typed_object_wrap((klass),(sval),(data_type))
#define TypedData_Make_Struct0(result,klass,type,size,data_type,sval) VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); (sval) = RBIMPL_CAST((type *)RTYPEDDATA_DATA(result)); RBIMPL_CAST( (void)(sval))
#define TypedData_Make_Struct(klass,type,data_type,sval) RB_GNUC_EXTENSION({ TypedData_Make_Struct0( data_struct_obj, klass, type, sizeof(type), data_type, sval); data_struct_obj; })
#define TypedData_Get_Struct(obj,type,data_type,sval) ((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))
#define RBIMPL_CTYPE_H
#define _CTYPE_H 1
#define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
#define __isctype(c,type) ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
#define __isascii(c) (((c) & ~0x7f) == 0)
#define __toascii(c) ((c) & 0x7f)
#define __exctype(name) extern int name (int) __THROW
#define __tobody(c,f,a,args) (__extension__ ({ int __res; if (sizeof (c) > 1) { if (__builtin_constant_p (c)) { int __c = (c); __res = __c < -128 || __c > 255 ? __c : (a)[__c]; } else __res = f args; } else __res = (a)[(int) (c)]; __res; }))
#define isalnum(c) __isctype((c), _ISalnum)
#define isalpha(c) __isctype((c), _ISalpha)
#define iscntrl(c) __isctype((c), _IScntrl)
#define isdigit(c) __isctype((c), _ISdigit)
#define islower(c) __isctype((c), _ISlower)
#define isgraph(c) __isctype((c), _ISgraph)
#define isprint(c) __isctype((c), _ISprint)
#define ispunct(c) __isctype((c), _ISpunct)
#define isspace(c) __isctype((c), _ISspace)
#define isupper(c) __isctype((c), _ISupper)
#define isxdigit(c) __isctype((c), _ISxdigit)
#define isblank(c) __isctype((c), _ISblank)
#define tolower(c) __tobody (c, tolower, *__ctype_tolower_loc (), (c))
#define toupper(c) __tobody (c, toupper, *__ctype_toupper_loc (), (c))
#define isascii(c) __isascii (c)
#define toascii(c) __toascii (c)
#define _tolower(c) ((int) (*__ctype_tolower_loc ())[(int) (c)])
#define _toupper(c) ((int) (*__ctype_toupper_loc ())[(int) (c)])
#define __isctype_l(c,type,locale) ((locale)->__ctype_b[(int) (c)] & (unsigned short int) type)
#define __exctype_l(name) extern int name (int, locale_t) __THROW
#define __tolower_l(c,locale) __tobody (c, __tolower_l, (locale)->__ctype_tolower, (c, locale))
#define __toupper_l(c,locale) __tobody (c, __toupper_l, (locale)->__ctype_toupper, (c, locale))
#define tolower_l(c,locale) __tolower_l ((c), (locale))
#define toupper_l(c,locale) __toupper_l ((c), (locale))
#define __isalnum_l(c,l) __isctype_l((c), _ISalnum, (l))
#define __isalpha_l(c,l) __isctype_l((c), _ISalpha, (l))
#define __iscntrl_l(c,l) __isctype_l((c), _IScntrl, (l))
#define __isdigit_l(c,l) __isctype_l((c), _ISdigit, (l))
#define __islower_l(c,l) __isctype_l((c), _ISlower, (l))
#define __isgraph_l(c,l) __isctype_l((c), _ISgraph, (l))
#define __isprint_l(c,l) __isctype_l((c), _ISprint, (l))
#define __ispunct_l(c,l) __isctype_l((c), _ISpunct, (l))
#define __isspace_l(c,l) __isctype_l((c), _ISspace, (l))
#define __isupper_l(c,l) __isctype_l((c), _ISupper, (l))
#define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l))
#define __isblank_l(c,l) __isctype_l((c), _ISblank, (l))
#define __isascii_l(c,l) ((l), __isascii (c))
#define __toascii_l(c,l) ((l), __toascii (c))
#define isalnum_l(c,l) __isalnum_l ((c), (l))
#define isalpha_l(c,l) __isalpha_l ((c), (l))
#define iscntrl_l(c,l) __iscntrl_l ((c), (l))
#define isdigit_l(c,l) __isdigit_l ((c), (l))
#define islower_l(c,l) __islower_l ((c), (l))
#define isgraph_l(c,l) __isgraph_l ((c), (l))
#define isprint_l(c,l) __isprint_l ((c), (l))
#define ispunct_l(c,l) __ispunct_l ((c), (l))
#define isspace_l(c,l) __isspace_l ((c), (l))
#define isupper_l(c,l) __isupper_l ((c), (l))
#define isxdigit_l(c,l) __isxdigit_l ((c), (l))
#define isblank_l(c,l) __isblank_l ((c), (l))
#define isascii_l(c,l) __isascii_l ((c), (l))
#define toascii_l(c,l) __toascii_l ((c), (l))
#define ISASCII rb_isascii
#define ISPRINT rb_isprint
#define ISGRAPH rb_isgraph
#define ISSPACE rb_isspace
#define ISUPPER rb_isupper
#define ISLOWER rb_islower
#define ISALNUM rb_isalnum
#define ISALPHA rb_isalpha
#define ISDIGIT rb_isdigit
#define ISXDIGIT rb_isxdigit
#define ISBLANK rb_isblank
#define ISCNTRL rb_iscntrl
#define ISPUNCT rb_ispunct
#define TOUPPER rb_toupper
#define TOLOWER rb_tolower
#define STRCASECMP st_locale_insensitive_strcasecmp
#define STRNCASECMP st_locale_insensitive_strncasecmp
#define STRTOUL ruby_strtoul
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_EVAL_H
#pragma GCC visibility push(default)
#define rb_funcall2 rb_funcallv
#define rb_funcall3 rb_funcallv_public
#pragma GCC visibility pop
#define RBIMPL_EVENT_H
#define RUBY_EVENT_NONE 0x0000
#define RUBY_EVENT_LINE 0x0001
#define RUBY_EVENT_CLASS 0x0002
#define RUBY_EVENT_END 0x0004
#define RUBY_EVENT_CALL 0x0008
#define RUBY_EVENT_RETURN 0x0010
#define RUBY_EVENT_C_CALL 0x0020
#define RUBY_EVENT_C_RETURN 0x0040
#define RUBY_EVENT_RAISE 0x0080
#define RUBY_EVENT_ALL 0x00ff
#define RUBY_EVENT_B_CALL 0x0100
#define RUBY_EVENT_B_RETURN 0x0200
#define RUBY_EVENT_THREAD_BEGIN 0x0400
#define RUBY_EVENT_THREAD_END 0x0800
#define RUBY_EVENT_FIBER_SWITCH 0x1000
#define RUBY_EVENT_SCRIPT_COMPILED 0x2000
#define RUBY_EVENT_TRACEPOINT_ALL 0xffff
#define RUBY_EVENT_RESERVED_FOR_INTERNAL_USE 0x030000
#define RUBY_INTERNAL_EVENT_SWITCH 0x040000
#define RUBY_EVENT_SWITCH 0x040000
#define RUBY_INTERNAL_EVENT_NEWOBJ 0x100000
#define RUBY_INTERNAL_EVENT_FREEOBJ 0x200000
#define RUBY_INTERNAL_EVENT_GC_START 0x400000
#define RUBY_INTERNAL_EVENT_GC_END_MARK 0x800000
#define RUBY_INTERNAL_EVENT_GC_END_SWEEP 0x1000000
#define RUBY_INTERNAL_EVENT_GC_ENTER 0x2000000
#define RUBY_INTERNAL_EVENT_GC_EXIT 0x4000000
#define RUBY_INTERNAL_EVENT_OBJSPACE_MASK 0x7f00000
#define RUBY_INTERNAL_EVENT_MASK 0xffff0000
#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_GC_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_GLOB_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_GLOBALS_H
#pragma GCC visibility push(default)
#define RUBY_INTEGER_UNIFICATION 1
#define CLASS_OF rb_class_of
#pragma GCC visibility pop
#define RBIMPL_INTERPRETER_H
#pragma GCC visibility push(default)
#define RUBY_INIT_STACK VALUE variable_in_this_stack_frame; ruby_init_stack(&variable_in_this_stack_frame);
#pragma GCC visibility pop
#define RBIMPL_ITERATOR_H
#pragma GCC visibility push(default)
#define RB_BLOCK_CALL_FUNC_STRICT 1
#define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg,callback_arg) VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg
#pragma GCC visibility pop
#define RBIMPL_MEMORY_H
#define DSIZE_T uint128_t
#define RUBY_ALLOCV_LIMIT 1024
#define RB_GC_GUARD(v) (*__extension__ ({ volatile VALUE *rb_gc_guarded_ptr = &(v); __asm__("" : : "m"(rb_gc_guarded_ptr)); rb_gc_guarded_ptr; }))
#define RB_ALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))
#define RB_ALLOC(type) RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))
#define RB_ZALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))
#define RB_ZALLOC(type) (RB_ZALLOC_N(type, 1))
#define RB_REALLOC_N(var,type,n) ((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))
#define ALLOCA_N(type,n) RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))
#define RB_ALLOCV(v,n) ((n) < RUBY_ALLOCV_LIMIT ? ((v) = 0, alloca(n)) : rb_alloc_tmp_buffer(&(v), (n)))
#define RB_ALLOCV_N(type,v,n) RBIMPL_CAST((type *) (((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? ((v) = 0, alloca((n) * sizeof(type))) : rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))))
#define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v))
#define MEMZERO(p,type,n) memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))
#define MEMCPY(p1,p2,type,n) ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
#define ALLOC_N RB_ALLOC_N
#define ALLOC RB_ALLOC
#define ZALLOC_N RB_ZALLOC_N
#define ZALLOC RB_ZALLOC
#define REALLOC_N RB_REALLOC_N
#define ALLOCV RB_ALLOCV
#define ALLOCV_N RB_ALLOCV_N
#define ALLOCV_END RB_ALLOCV_END
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_MODULE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_NEWOBJ_H
#define RB_NEWOBJ(obj,type) type *(obj) = RBIMPL_CAST((type *)rb_newobj())
#define RB_NEWOBJ_OF(obj,type,klass,flags) type *(obj) = RBIMPL_CAST((type *)rb_newobj_of(klass, flags))
#define NEWOBJ RB_NEWOBJ
#define NEWOBJ_OF RB_NEWOBJ_OF
#define OBJSETUP rb_obj_setup
#define CLONESETUP rb_clone_setup
#define DUPSETUP rb_dup_setup
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_SCAN_ARGS_H
#define RBIMPL_ATTR_DIAGNOSE_IF_H
#define RBIMPL_ATTR_DIAGNOSE_IF(_,__,___)
#define RBIMPL_INTERN_ARRAY_H
#pragma GCC visibility push(default)
#define rb_ary_tmp_new rb_ary_hidden_new
#define rb_ary_new2 rb_ary_new_capa
#define rb_ary_new3 rb_ary_new_from_args
#define rb_ary_new4 rb_ary_new_from_values
#pragma GCC visibility pop
#define RBIMPL_INTERN_ERROR_H
#define UNLIMITED_ARGUMENTS (-1)
#define rb_exc_new2 rb_exc_new_cstr
#define rb_exc_new3 rb_exc_new_str
#define rb_check_arity rb_check_arity
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_check_frozen_internal(obj) do { VALUE frozen_obj = (obj); if (RB_UNLIKELY(RB_OBJ_FROZEN(frozen_obj))) { rb_error_frozen_object(frozen_obj); } } while (0)
#define rb_check_frozen rb_check_frozen_inline
#define RBIMPL_INTERN_HASH_H
#pragma GCC visibility push(default)
#define st_foreach_safe rb_st_foreach_safe
#pragma GCC visibility pop
#define RBIMPL_INTERN_PROC_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0
#define RB_SCAN_ARGS_KEYWORDS 1
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3
#define RB_NO_KEYWORDS 0
#define RB_PASS_KEYWORDS 1
#define RB_PASS_CALLED_KEYWORDS rb_keyword_given_p()
#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)
#define rb_scan_args_count_end(fmt,ofs,vari) ((fmt)[ofs] ? -1 : (vari))
#define rb_scan_args_count_block(fmt,ofs,vari) ((fmt)[ofs]!='&' ? rb_scan_args_count_end(fmt, ofs, vari) : rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_hash(fmt,ofs,vari) ((fmt)[ofs]!=':' ? rb_scan_args_count_block(fmt, ofs, vari) : rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_trail(fmt,ofs,vari) (!rb_scan_args_isdigit((fmt)[ofs]) ? rb_scan_args_count_hash(fmt, ofs, vari) : rb_scan_args_count_hash(fmt, (ofs)+1, (vari)+((fmt)[ofs]-'0')))
#define rb_scan_args_count_var(fmt,ofs,vari) ((fmt)[ofs]!='*' ? rb_scan_args_count_trail(fmt, ofs, vari) : rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_opt(fmt,ofs,vari) (!rb_scan_args_isdigit((fmt)[ofs]) ? rb_scan_args_count_var(fmt, ofs, vari) : rb_scan_args_count_var(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
#define rb_scan_args_count_lead(fmt,ofs,vari) (!rb_scan_args_isdigit((fmt)[ofs]) ? rb_scan_args_count_var(fmt, ofs, vari) : rb_scan_args_count_opt(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)
#define rb_scan_args_verify(fmt,varc) (sizeof(char[1-2*(rb_scan_args_count(fmt)<0)])!=1 ? rb_scan_args_bad_format(fmt) : sizeof(char[1-2*(rb_scan_args_count(fmt)!=(varc))])!=1 ? rb_scan_args_length_mismatch(fmt, varc) : RBIMPL_ASSERT_NOTHING)
#define rb_scan_args0(argc,argv,fmt,varc,vars) rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, rb_scan_args_n_lead(fmt), rb_scan_args_n_opt(fmt), rb_scan_args_n_trail(fmt), rb_scan_args_f_var(fmt), rb_scan_args_f_hash(fmt), rb_scan_args_f_block(fmt), (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
#define rb_scan_args_kw0(kw_flag,argc,argv,fmt,varc,vars) rb_scan_args_set(kw_flag, argc, argv, rb_scan_args_n_lead(fmt), rb_scan_args_n_opt(fmt), rb_scan_args_n_trail(fmt), rb_scan_args_f_var(fmt), rb_scan_args_f_hash(fmt), rb_scan_args_f_block(fmt), (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
#define rb_scan_args_next_param() vars[vari++]
#undef rb_scan_args_next_param
#define rb_scan_args(argc,argvp,fmt,...) __builtin_choose_expr( __builtin_constant_p(fmt), rb_scan_args0( argc, argvp, fmt, (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), ((VALUE*[]){__VA_ARGS__})), (rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
#define rb_scan_args_kw(kw_flag,argc,argvp,fmt,...) __builtin_choose_expr( __builtin_constant_p(fmt), rb_scan_args_kw0( kw_flag, argc, argvp, fmt, (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), ((VALUE*[]){__VA_ARGS__})), (rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
#define RBIMPL_SYMBOL_H
#define RB_ID2SYM rb_id2sym
#define RB_SYM2ID rb_sym2id
#define ID2SYM RB_ID2SYM
#define SYM2ID RB_SYM2ID
#define CONST_ID_CACHE RUBY_CONST_ID_CACHE
#define CONST_ID RUBY_CONST_ID
#define rb_intern_const rb_intern_const
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_CONST_ID_CACHE(result,str) { static ID rb_intern_id_cache; rbimpl_intern_const(&rb_intern_id_cache, (str)); result rb_intern_id_cache; }
#define RUBY_CONST_ID(var,str) do { static ID rbimpl_id; (var) = rbimpl_intern_const(&rbimpl_id, (str)); } while (0)
#define rb_intern(str) (RBIMPL_CONSTANT_P(str) ? __extension__ ({ static ID rbimpl_id; rbimpl_intern_const(&rbimpl_id, (str)); }) : (rb_intern)(str))
#define RBIMPL_VARIABLE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_BACKWARD2_INTTYPES_H
#define PRI_INT_PREFIX ""
#define PRI_LONG_PREFIX "l"
#define PRI_SHORT_PREFIX "h"
#define PRI_64_PREFIX PRI_LONG_PREFIX
#define RUBY_PRI_VALUE_MARK "\v"
#define PRIdVALUE PRI_VALUE_PREFIX"d"
#define PRIoVALUE PRI_VALUE_PREFIX"o"
#define PRIuVALUE PRI_VALUE_PREFIX"u"
#define PRIxVALUE PRI_VALUE_PREFIX"x"
#define PRIXVALUE PRI_VALUE_PREFIX"X"
#define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK
#define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
#define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
#define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
#define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
#define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
#define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
#define PRIdSIZE PRI_SIZE_PREFIX"d"
#define PRIiSIZE PRI_SIZE_PREFIX"i"
#define PRIoSIZE PRI_SIZE_PREFIX"o"
#define PRIuSIZE PRI_SIZE_PREFIX"u"
#define PRIxSIZE PRI_SIZE_PREFIX"x"
#define PRIXSIZE PRI_SIZE_PREFIX"X"
#pragma GCC visibility push(default)
#define USE_SYMBOL_AS_METHOD_NAME 1
#define FilePathValue(v) (RB_GC_GUARD(v) = rb_get_path(v))
#define FilePathStringValue(v) ((v) = rb_get_path(v))
#define rb_varargs_argc_check_runtime(argc,vargc) (((argc) <= (vargc)) ? (argc) : (rb_fatal("argc(%d) exceeds actual arguments(%d)", argc, vargc), 0))
#define rb_varargs_argc_valid_p(argc,vargc) ((argc) == 0 ? (vargc) <= 1 : (argc) == (vargc))
#define rb_varargs_argc_check(argc,vargc) __builtin_choose_expr(__builtin_constant_p(argc), (rb_varargs_argc_valid_p(argc, vargc) ? (argc) : rb_varargs_bad_length(argc, vargc)), rb_varargs_argc_check_runtime(argc, vargc))
#define RUBY_INTERN_H 1
#define RBIMPL_INTERN_BIGNUM_H
#pragma GCC visibility push(default)
#define rb_big2int(x) rb_big2long(x)
#define rb_big2uint(x) rb_big2ulong(x)
#define INTEGER_PACK_MSWORD_FIRST 0x01
#define INTEGER_PACK_LSWORD_FIRST 0x02
#define INTEGER_PACK_MSBYTE_FIRST 0x10
#define INTEGER_PACK_LSBYTE_FIRST 0x20
#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
#define INTEGER_PACK_2COMP 0x80
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
#define INTEGER_PACK_FORCE_BIGNUM 0x100
#define INTEGER_PACK_NEGATIVE 0x200
#define INTEGER_PACK_LITTLE_ENDIAN (INTEGER_PACK_LSWORD_FIRST | INTEGER_PACK_LSBYTE_FIRST)
#define INTEGER_PACK_BIG_ENDIAN (INTEGER_PACK_MSWORD_FIRST | INTEGER_PACK_MSBYTE_FIRST)
#pragma GCC visibility pop
#define RBIMPL_INTERN_COMPAR_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_COMPLEX_H
#pragma GCC visibility push(default)
#define rb_complex_raw1(x) rb_complex_raw((x), INT2FIX(0))
#define rb_complex_raw2(x,y) rb_complex_raw((x), (y))
#define rb_complex_new1(x) rb_complex_new((x), INT2FIX(0))
#define rb_complex_new2(x,y) rb_complex_new((x), (y))
#define rb_complex_add rb_complex_plus
#define rb_complex_sub rb_complex_minus
#define rb_complex_nagate rb_complex_uminus
#define rb_Complex1(x) rb_Complex((x), INT2FIX(0))
#define rb_Complex2(x,y) rb_Complex((x), (y))
#pragma GCC visibility pop
#define RBIMPL_INTERN_CONT_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_DIR_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_ENUM_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_ENUMERATOR_H
#define RBIMPL_INTERN_EVAL_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define SIZED_ENUMERATOR(obj,argc,argv,size_fn) rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn))
#define SIZED_ENUMERATOR_KW(obj,argc,argv,size_fn,kw_splat) rb_enumeratorize_with_size_kw((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn), (kw_splat))
#define RETURN_SIZED_ENUMERATOR(obj,argc,argv,size_fn) do { if (!rb_block_given_p()) return SIZED_ENUMERATOR(obj, argc, argv, size_fn); } while (0)
#define RETURN_SIZED_ENUMERATOR_KW(obj,argc,argv,size_fn,kw_splat) do { if (!rb_block_given_p()) return SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat); } while (0)
#define RETURN_ENUMERATOR(obj,argc,argv) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)
#define RETURN_ENUMERATOR_KW(obj,argc,argv,kw_splat) RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, 0, kw_splat)
#define RBIMPL_INTERN_FILE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_GC_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_IO_H
#pragma GCC visibility push(default)
#define rb_defout rb_stdout
#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd)
#pragma GCC visibility pop
#define RBIMPL_INTERN_LOAD_H
#pragma GCC visibility push(default)
#define RB_EXT_RACTOR_SAFE(f) rb_ext_ractor_safe(f)
#define HAVE_RB_EXT_RACTOR_SAFE 1
#pragma GCC visibility pop
#define RBIMPL_INTERN_MARSHAL_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_NUMERIC_H
#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_OBJECT_H
#pragma GCC visibility push(default)
#define RB_OBJ_INIT_COPY(obj,orig) ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
#define OBJ_INIT_COPY(obj,orig) RB_OBJ_INIT_COPY(obj, orig)
#pragma GCC visibility pop
#define RBIMPL_INTERN_PARSE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_PROCESS_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_RANDOM_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_RANGE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_RATIONAL_H
#pragma GCC visibility push(default)
#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))
#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))
#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))
#define rb_rational_new2(x,y) rb_rational_new((x), (y))
#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))
#define rb_Rational2(x,y) rb_Rational((x), (y))
#pragma GCC visibility pop
#define RBIMPL_INTERN_RE_H
#pragma GCC visibility push(default)
#define rb_memcmp memcmp
#define HAVE_RB_REG_NEW_STR 1
#pragma GCC visibility pop
#define RBIMPL_INTERN_RUBY_H
#pragma GCC visibility push(default)
#define rb_argv rb_get_argv()
#pragma GCC visibility pop
#define RBIMPL_INTERN_SELECT_H
#define RBIMPL_INTERN_SELECT_LARGESIZE_H
#define rb_fd_ptr rb_fd_ptr
#define rb_fd_max rb_fd_max
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_SIGNAL_H
#pragma GCC visibility push(default)
#define posix_signal ruby_posix_signal
#pragma GCC visibility pop
#define RBIMPL_INTERN_SPRINTF_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_STRING_H
#pragma GCC visibility push(default)
#define rb_str_dup_frozen rb_str_new_frozen
#define rb_hash_uint32(h,i) st_hash_uint32((h), (i))
#define rb_hash_uint(h,i) st_hash_uint((h), (i))
#define rb_hash_end(h) st_hash_end(h)
#define rb_str_new(str,len) ((RBIMPL_CONSTANT_P(str) && RBIMPL_CONSTANT_P(len) ? rb_str_new_static : rb_str_new) ((str), (len)))
#define rb_str_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_str_new_cstr : rb_str_new_cstr) (str))
#define rb_usascii_str_new(str,len) ((RBIMPL_CONSTANT_P(str) && RBIMPL_CONSTANT_P(len) ? rb_usascii_str_new_static : rb_usascii_str_new) ((str), (len)))
#define rb_utf8_str_new(str,len) ((RBIMPL_CONSTANT_P(str) && RBIMPL_CONSTANT_P(len) ? rb_utf8_str_new_static : rb_utf8_str_new) ((str), (len)))
#define rb_usascii_str_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_usascii_str_new_cstr : rb_usascii_str_new_cstr) (str))
#define rb_utf8_str_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_utf8_str_new_cstr : rb_utf8_str_new_cstr) (str))
#define rb_external_str_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_external_str_new_cstr : rb_external_str_new_cstr) (str))
#define rb_locale_str_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_locale_str_new_cstr : rb_locale_str_new_cstr) (str))
#define rb_str_buf_new_cstr(str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_str_buf_new_cstr : rb_str_buf_new_cstr) (str))
#define rb_str_cat_cstr(buf,str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_str_cat_cstr : rb_str_cat_cstr) ((buf), (str)))
#define rb_exc_new_cstr(exc,str) ((RBIMPL_CONSTANT_P(str) ? rbimpl_exc_new_cstr : rb_exc_new_cstr) ((exc), (str)))
#define rb_str_new2 rb_str_new_cstr
#define rb_str_new3 rb_str_new_shared
#define rb_str_new4 rb_str_new_frozen
#define rb_str_new5 rb_str_new_with_class
#define rb_str_buf_new2 rb_str_buf_new_cstr
#define rb_usascii_str_new2 rb_usascii_str_new_cstr
#define rb_str_buf_cat rb_str_cat
#define rb_str_buf_cat2 rb_str_cat_cstr
#define rb_str_cat2 rb_str_cat_cstr
#define rb_strlen_lit(str) (sizeof(str "") - 1)
#define rb_str_new_lit(str) rb_str_new_static((str), rb_strlen_lit(str))
#define rb_usascii_str_new_lit(str) rb_usascii_str_new_static((str), rb_strlen_lit(str))
#define rb_utf8_str_new_lit(str) rb_utf8_str_new_static((str), rb_strlen_lit(str))
#define rb_enc_str_new_lit(str,enc) rb_enc_str_new_static((str), rb_strlen_lit(str), (enc))
#define rb_str_new_literal(str) rb_str_new_lit(str)
#define rb_usascii_str_new_literal(str) rb_usascii_str_new_lit(str)
#define rb_utf8_str_new_literal(str) rb_utf8_str_new_lit(str)
#define rb_enc_str_new_literal(str,enc) rb_enc_str_new_lit(str, enc)
#pragma GCC visibility pop
#define RBIMPL_INTERN_STRUCT_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_THREAD_H
#pragma GCC visibility push(default)
#define RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1)
#define RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1)
#pragma GCC visibility pop
#define RBIMPL_INTERN_TIME_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RBIMPL_INTERN_VARIABLE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_VM 1
#define HAVE_NATIVETHREAD
#define InitVM(ext) {void InitVM_ ##ext(void);InitVM_ ##ext();}
#define rb_yield_values(argc,...) __extension__({ const int rb_yield_values_argc = (argc); const VALUE rb_yield_values_args[] = {__VA_ARGS__}; const int rb_yield_values_nargs = (int)(sizeof(rb_yield_values_args) / sizeof(VALUE)); rb_yield_values2( rb_varargs_argc_check(rb_yield_values_argc, rb_yield_values_nargs), rb_yield_values_nargs ? rb_yield_values_args : NULL); })
#define rb_funcall(recv,mid,argc,...) __extension__({ const int rb_funcall_argc = (argc); const VALUE rb_funcall_args[] = {__VA_ARGS__}; const int rb_funcall_nargs = (int)(sizeof(rb_funcall_args) / sizeof(VALUE)); rb_funcallv(recv, mid, rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), rb_funcall_nargs ? rb_funcall_args : NULL); })
#define RUBY_SUBST_H 1
#undef snprintf
#undef vsnprintf
#define snprintf ruby_snprintf
#define vsnprintf ruby_vsnprintf
#pragma GCC visibility pop
#define RUBY_VM_CORE_H
#define N_OR_RUBY_DEBUG(n) (((n) > 0) ? (n) : RUBY_DEBUG)
#define VM_CHECK_MODE N_OR_RUBY_DEBUG(0)
#define VMDEBUG 0
#define _SIGNAL_H
#define _BITS_SIGNUM_H 1
#define _BITS_SIGNUM_GENERIC_H 1
#define SIG_ERR ((__sighandler_t) -1)
#define SIG_DFL ((__sighandler_t) 0)
#define SIG_IGN ((__sighandler_t) 1)
#define SIG_HOLD ((__sighandler_t) 2)
#define SIGINT 2
#define SIGILL 4
#define SIGABRT 6
#define SIGFPE 8
#define SIGSEGV 11
#define SIGTERM 15
#define SIGHUP 1
#define SIGQUIT 3
#define SIGTRAP 5
#define SIGKILL 9
#define SIGBUS 10
#define SIGSYS 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGURG 16
#define SIGSTOP 17
#define SIGTSTP 18
#define SIGCONT 19
#define SIGCHLD 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGPOLL 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGUSR1 30
#define SIGUSR2 31
#define SIGWINCH 28
#define SIGIO SIGPOLL
#define SIGIOT SIGABRT
#define SIGCLD SIGCHLD
#define __SIGRTMIN 32
#define __SIGRTMAX __SIGRTMIN
#define _NSIG (__SIGRTMAX + 1)
#define SIGSTKFLT 16
#define SIGPWR 30
#undef SIGBUS
#define SIGBUS 7
#undef SIGUSR1
#define SIGUSR1 10
#undef SIGUSR2
#define SIGUSR2 12
#undef SIGCHLD
#define SIGCHLD 17
#undef SIGCONT
#define SIGCONT 18
#undef SIGSTOP
#define SIGSTOP 19
#undef SIGTSTP
#define SIGTSTP 20
#undef SIGURG
#define SIGURG 23
#undef SIGPOLL
#define SIGPOLL 29
#undef SIGSYS
#define SIGSYS 31
#undef __SIGRTMAX
#define __SIGRTMAX 64
#define __sig_atomic_t_defined 1
#define __siginfo_t_defined 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define ____sigval_t_defined
#define __SI_MAX_SIZE 128
#define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
#define _BITS_SIGINFO_ARCH_H 1
#define __SI_ALIGNMENT
#define __SI_BAND_TYPE long int
#define __SI_CLOCK_T __clock_t
#define __SI_ERRNO_THEN_CODE 1
#define __SI_HAVE_SIGSYS 1
#define __SI_SIGFAULT_ADDL
#define si_pid _sifields._kill.si_pid
#define si_uid _sifields._kill.si_uid
#define si_timerid _sifields._timer.si_tid
#define si_overrun _sifields._timer.si_overrun
#define si_status _sifields._sigchld.si_status
#define si_utime _sifields._sigchld.si_utime
#define si_stime _sifields._sigchld.si_stime
#define si_value _sifields._rt.si_sigval
#define si_int _sifields._rt.si_sigval.sival_int
#define si_ptr _sifields._rt.si_sigval.sival_ptr
#define si_addr _sifields._sigfault.si_addr
#define si_addr_lsb _sifields._sigfault.si_addr_lsb
#define si_lower _sifields._sigfault._bounds._addr_bnd._lower
#define si_upper _sifields._sigfault._bounds._addr_bnd._upper
#define si_pkey _sifields._sigfault._bounds._pkey
#define si_band _sifields._sigpoll.si_band
#define si_fd _sifields._sigpoll.si_fd
#define si_call_addr _sifields._sigsys._call_addr
#define si_syscall _sifields._sigsys._syscall
#define si_arch _sifields._sigsys._arch
#define _BITS_SIGINFO_CONSTS_H 1
#define __SI_ASYNCIO_AFTER_SIGIO 1
#define SI_ASYNCNL SI_ASYNCNL
#define SI_TKILL SI_TKILL
#define SI_SIGIO SI_SIGIO
#define SI_ASYNCIO SI_ASYNCIO
#define SI_MESGQ SI_MESGQ
#define SI_TIMER SI_TIMER
#define SI_ASYNCIO SI_ASYNCIO
#define SI_QUEUE SI_QUEUE
#define SI_USER SI_USER
#define SI_KERNEL SI_KERNEL
#define ILL_ILLOPC ILL_ILLOPC
#define ILL_ILLOPN ILL_ILLOPN
#define ILL_ILLADR ILL_ILLADR
#define ILL_ILLTRP ILL_ILLTRP
#define ILL_PRVOPC ILL_PRVOPC
#define ILL_PRVREG ILL_PRVREG
#define ILL_COPROC ILL_COPROC
#define ILL_BADSTK ILL_BADSTK
#define FPE_INTDIV FPE_INTDIV
#define FPE_INTOVF FPE_INTOVF
#define FPE_FLTDIV FPE_FLTDIV
#define FPE_FLTOVF FPE_FLTOVF
#define FPE_FLTUND FPE_FLTUND
#define FPE_FLTRES FPE_FLTRES
#define FPE_FLTINV FPE_FLTINV
#define FPE_FLTSUB FPE_FLTSUB
#define SEGV_MAPERR SEGV_MAPERR
#define SEGV_ACCERR SEGV_ACCERR
#define SEGV_BNDERR SEGV_BNDERR
#define SEGV_PKUERR SEGV_PKUERR
#define BUS_ADRALN BUS_ADRALN
#define BUS_ADRERR BUS_ADRERR
#define BUS_OBJERR BUS_OBJERR
#define BUS_MCEERR_AR BUS_MCEERR_AR
#define BUS_MCEERR_AO BUS_MCEERR_AO
#define TRAP_BRKPT TRAP_BRKPT
#define TRAP_TRACE TRAP_TRACE
#define CLD_EXITED CLD_EXITED
#define CLD_KILLED CLD_KILLED
#define CLD_DUMPED CLD_DUMPED
#define CLD_TRAPPED CLD_TRAPPED
#define CLD_STOPPED CLD_STOPPED
#define CLD_CONTINUED CLD_CONTINUED
#define POLL_IN POLL_IN
#define POLL_OUT POLL_OUT
#define POLL_MSG POLL_MSG
#define POLL_ERR POLL_ERR
#define POLL_PRI POLL_PRI
#define POLL_HUP POLL_HUP
#define _BITS_SIGINFO_CONSTS_ARCH_H 1
#define __sigval_t_defined
#define __sigevent_t_defined 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define __SIGEV_MAX_SIZE 64
#define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
#define sigev_notify_function _sigev_un._sigev_thread._function
#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
#define _BITS_SIGEVENT_CONSTS_H 1
#define SIGEV_SIGNAL SIGEV_SIGNAL
#define SIGEV_NONE SIGEV_NONE
#define SIGEV_THREAD SIGEV_THREAD
#define SIGEV_THREAD_ID SIGEV_THREAD_ID
#define sigmask(sig) ((int)(1u << ((sig) - 1)))
#define NSIG _NSIG
#define _BITS_SIGACTION_H 1
#define sa_handler __sigaction_handler.sa_handler
#define sa_sigaction __sigaction_handler.sa_sigaction
#define SA_NOCLDSTOP 1
#define SA_NOCLDWAIT 2
#define SA_SIGINFO 4
#define SA_ONSTACK 0x08000000
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
#define SA_INTERRUPT 0x20000000
#define SA_NOMASK SA_NODEFER
#define SA_ONESHOT SA_RESETHAND
#define SA_STACK SA_ONSTACK
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
#define _BITS_SIGCONTEXT_H 1
#define FP_XSTATE_MAGIC1 0x46505853U
#define FP_XSTATE_MAGIC2 0x46505845U
#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2)
#define __need_size_t
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define __stack_t_defined 1
#define __need_size_t
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define _SYS_UCONTEXT_H 1
#define __ctx(fld) fld
#define __NGREG 23
#define NGREG __NGREG
#define REG_R8 REG_R8
#define REG_R9 REG_R9
#define REG_R10 REG_R10
#define REG_R11 REG_R11
#define REG_R12 REG_R12
#define REG_R13 REG_R13
#define REG_R14 REG_R14
#define REG_R15 REG_R15
#define REG_RDI REG_RDI
#define REG_RSI REG_RSI
#define REG_RBP REG_RBP
#define REG_RBX REG_RBX
#define REG_RDX REG_RDX
#define REG_RAX REG_RAX
#define REG_RCX REG_RCX
#define REG_RSP REG_RSP
#define REG_RIP REG_RIP
#define REG_EFL REG_EFL
#define REG_CSGSFS REG_CSGSFS
#define REG_ERR REG_ERR
#define REG_TRAPNO REG_TRAPNO
#define REG_OLDMASK REG_OLDMASK
#define REG_CR2 REG_CR2
#undef __ctx
#define _BITS_SIGSTACK_H 1
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
#define _BITS_SS_FLAGS_H 1
#define SS_ONSTACK SS_ONSTACK
#define SS_DISABLE SS_DISABLE
#define __sigstack_defined 1
#define _BITS_SIGTHREAD_H 1
#define SIGRTMIN (__libc_current_sigrtmin ())
#define SIGRTMAX (__libc_current_sigrtmax ())
#define RUBY_TOPLEVEL_ASSERT_H
#undef assert
#define assert RUBY_ASSERT_NDEBUG
#define VM_ASSERT(expr) ((void)0)
#define VM_UNREACHABLE(func) UNREACHABLE
#define RUBY_DEBUG_THREAD_SCHEDULE()
#define RUBY_ASSERT_MUTEX_OWNED(mutex) VM_ASSERT(rb_mutex_owned_p(mutex))
#define RUBY_ASSERT_CRITICAL_SECTION_ENTER()
#define RUBY_ASSERT_CRITICAL_SECTION_LEAVE()
#define _SETJMP_H 1
#define _BITS_SETJMP_H 1
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define setjmp(env) _setjmp (env)
#define sigsetjmp(env,savemask) __sigsetjmp (env, savemask)
#define RB_THREAD_T_HAS_NATIVE_ID
#define CCAN_LIST_H
#undef _ASSERT_H
#undef assert
#undef __ASSERT_VOID_CAST
#undef assert_perror
#define _ASSERT_H 1
#define __ASSERT_VOID_CAST (void)
#define assert(expr) (__ASSERT_VOID_CAST (0))
#define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
#undef static_assert
#define static_assert _Static_assert
#define CCAN_STR_H
#define stringify(expr) ccan_stringify_1(expr)
#define ccan_stringify(expr) ccan_stringify_1(expr)
#define ccan_stringify_1(expr) #expr
#define CCAN_CONTAINER_OF_H
#define CCAN_CHECK_TYPE_H
#define ccan_check_type(expr,type) ((typeof(expr) *)0 != (type *)0)
#define ccan_check_types_match(expr1,expr2) ((typeof(expr1) *)0 != (typeof(expr2) *)0)
#define ccan_container_of(member_ptr,containing_type,member) ((containing_type *) ((char *)(member_ptr) - ccan_container_off(containing_type, member)) + ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))
#define ccan_container_of_or_null(member_ptr,containing_type,member) ((containing_type *) ccan_container_of_or_null_(member_ptr, ccan_container_off(containing_type, member)) + ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))
#define ccan_container_off(containing_type,member) offsetof(containing_type, member)
#define ccan_container_of_var(member_ptr,container_var,member) ccan_container_of(member_ptr, typeof(*container_var), member)
#define ccan_container_off_var(var,member) ccan_container_off(typeof(*var), member)
#define CCAN_LIST_LOC __FILE__ ":" ccan_stringify(__LINE__)
#define ccan_list_debug(h,loc) ((void)loc, h)
#define ccan_list_debug_node(n,loc) ((void)loc, n)
#define CCAN_LIST_HEAD_INIT(name) { { &(name).n, &(name).n } }
#define CCAN_LIST_HEAD(name) struct ccan_list_head name = CCAN_LIST_HEAD_INIT(name)
#define ccan_list_add_after(h,p,n) ccan_list_add_after_(h, p, n, CCAN_LIST_LOC)
#define ccan_list_add(h,n) ccan_list_add_(h, n, CCAN_LIST_LOC)
#define ccan_list_add_before(h,p,n) ccan_list_add_before_(h, p, n, CCAN_LIST_LOC)
#define ccan_list_add_tail(h,n) ccan_list_add_tail_(h, n, CCAN_LIST_LOC)
#define ccan_list_empty(h) ccan_list_empty_(h, CCAN_LIST_LOC)
#define ccan_list_empty_nodebug(h) ccan_list_empty(h)
#define ccan_list_del(n) ccan_list_del_(n, CCAN_LIST_LOC)
#define ccan_list_del_init(n) ccan_list_del_init_(n, CCAN_LIST_LOC)
#define ccan_list_swap(o,n) ccan_list_swap_(o, n, CCAN_LIST_LOC)
#define ccan_list_entry(n,type,member) ccan_container_of(n, type, member)
#define ccan_list_top(h,type,member) ((type *)ccan_list_top_((h), ccan_list_off_(type, member)))
#define ccan_list_pop(h,type,member) ((type *)ccan_list_pop_((h), ccan_list_off_(type, member)))
#define ccan_list_tail(h,type,member) ((type *)ccan_list_tail_((h), ccan_list_off_(type, member)))
#define ccan_list_for_each(h,i,member) ccan_list_for_each_off(h, i, ccan_list_off_var_(i, member))
#define ccan_list_for_each_rev(h,i,member) ccan_list_for_each_rev_off(h, i, ccan_list_off_var_(i, member))
#define ccan_list_for_each_rev_safe(h,i,nxt,member) ccan_list_for_each_rev_safe_off(h, i, nxt, ccan_list_off_var_(i, member))
#define ccan_list_for_each_safe(h,i,nxt,member) ccan_list_for_each_safe_off(h, i, nxt, ccan_list_off_var_(i, member))
#define ccan_list_next(h,i,member) ((ccan_list_typeof(i))ccan_list_entry_or_null(ccan_list_debug(h, __FILE__ ":" ccan_stringify(__LINE__)), (i)->member.next, ccan_list_off_var_((i), member)))
#define ccan_list_prev(h,i,member) ((ccan_list_typeof(i))ccan_list_entry_or_null(ccan_list_debug(h, __FILE__ ":" ccan_stringify(__LINE__)), (i)->member.prev, ccan_list_off_var_((i), member)))
#define ccan_list_append_list(t,f) ccan_list_append_list_(t, f, __FILE__ ":" ccan_stringify(__LINE__))
#define ccan_list_prepend_list(t,f) ccan_list_prepend_list_(t, f, CCAN_LIST_LOC)
#define ccan_list_for_each_off_dir_(h,i,off,dir) for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, (off)); ccan_list_node_from_off_((void *)i, (off)) != &(h)->n; i = ccan_list_node_to_off_(ccan_list_node_from_off_((void *)i, (off))->dir, (off)))
#define ccan_list_for_each_safe_off_dir_(h,i,nxt,off,dir) for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, (off)), nxt = ccan_list_node_to_off_(ccan_list_node_from_off_(i, (off))->dir, (off)); ccan_list_node_from_off_(i, (off)) != &(h)->n; i = nxt, nxt = ccan_list_node_to_off_(ccan_list_node_from_off_(i, (off))->dir, (off)))
#define ccan_list_for_each_off(h,i,off) ccan_list_for_each_off_dir_((h),(i),(off),next)
#define ccan_list_for_each_rev_off(h,i,off) ccan_list_for_each_off_dir_((h),(i),(off),prev)
#define ccan_list_for_each_safe_off(h,i,nxt,off) ccan_list_for_each_safe_off_dir_((h),(i),(nxt),(off),next)
#define ccan_list_for_each_rev_safe_off(h,i,nxt,off) ccan_list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev)
#define ccan_list_entry_off(n,type,off) ((type *)ccan_list_node_from_off_((n), (off)))
#define ccan_list_head_off(h,type,off) ((type *)ccan_list_head_off((h), (off)))
#define ccan_list_tail_off(h,type,off) ((type *)ccan_list_tail_((h), (off)))
#define ccan_list_add_off(h,n,off) ccan_list_add((h), ccan_list_node_from_off_((n), (off)))
#define ccan_list_del_off(n,off) ccan_list_del(ccan_list_node_from_off_((n), (off)))
#define ccan_list_del_from_off(h,n,off) ccan_list_del_from(h, ccan_list_node_from_off_((n), (off)))
#define ccan_list_off_(type,member) (ccan_container_off(type, member) + ccan_check_type(((type *)0)->member, struct ccan_list_node))
#define ccan_list_off_var_(var,member) (ccan_container_off_var(var, member) + ccan_check_type(var->member, struct ccan_list_node))
#define ccan_list_typeof(var) typeof(var)
#define RUBY_ID_H
#define ID_STATIC_SYM RUBY_ID_STATIC_SYM
#define ID_SCOPE_SHIFT RUBY_ID_SCOPE_SHIFT
#define ID_SCOPE_MASK RUBY_ID_SCOPE_MASK
#define ID_LOCAL RUBY_ID_LOCAL
#define ID_INSTANCE RUBY_ID_INSTANCE
#define ID_GLOBAL RUBY_ID_GLOBAL
#define ID_ATTRSET RUBY_ID_ATTRSET
#define ID_CONST RUBY_ID_CONST
#define ID_CLASS RUBY_ID_CLASS
#define ID_JUNK RUBY_ID_JUNK
#define ID_INTERNAL RUBY_ID_INTERNAL
#define symIFUNC ID2SYM(idIFUNC)
#define symCFUNC ID2SYM(idCFUNC)
#define RUBY_TOKEN_DOT2 128
#define RUBY_TOKEN_DOT3 129
#define RUBY_TOKEN_BDOT2 130
#define RUBY_TOKEN_BDOT3 131
#define RUBY_TOKEN_UPLUS 132
#define RUBY_TOKEN_UMINUS 133
#define RUBY_TOKEN_POW 134
#define RUBY_TOKEN_CMP 135
#define RUBY_TOKEN_LSHFT 136
#define RUBY_TOKEN_RSHFT 137
#define RUBY_TOKEN_LEQ 138
#define RUBY_TOKEN_GEQ 139
#define RUBY_TOKEN_EQ 140
#define RUBY_TOKEN_EQQ 141
#define RUBY_TOKEN_NEQ 142
#define RUBY_TOKEN_MATCH 143
#define RUBY_TOKEN_NMATCH 144
#define RUBY_TOKEN_AREF 145
#define RUBY_TOKEN_ASET 146
#define RUBY_TOKEN_COLON2 147
#define RUBY_TOKEN_ANDOP 148
#define RUBY_TOKEN_OROP 149
#define RUBY_TOKEN_ANDDOT 150
#define RUBY_TOKEN(t) RUBY_TOKEN_ ##t
#define RUBY_TOKEN2ID_TYPE(tok,type) ((tok<<RUBY_ID_SCOPE_SHIFT)|type|RUBY_ID_STATIC_SYM)
#define TOKEN2LOCALID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_LOCAL)
#define TOKEN2INSTANCEID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_INSTANCE)
#define TOKEN2GLOBALID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_GLOBAL)
#define TOKEN2CONSTID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_CONST)
#define TOKEN2CLASSID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_CLASS)
#define TOKEN2ATTRSETID(tok) RUBY_TOKEN2ID_TYPE(tok, RUBY_ID_ATTRSET)
#define DEFINE_LOCALID_FROM_TOKEN(n) id ##n = TOKEN2LOCALID(t ##n)
#define DEFINE_INSTANCEID_FROM_TOKEN(n) id ##n = TOKEN2INSTANCEID(t ##n)
#define DEFINE_GLOBALID_FROM_TOKEN(n) id ##n = TOKEN2GLOBALID(t ##n)
#define DEFINE_CONSTID_FROM_TOKEN(n) id ##n = TOKEN2CONSTID(t ##n)
#define DEFINE_CLASSID_FROM_TOKEN(n) id ##n = TOKEN2CLASSID(t ##n)
#define DEFINE_ATTRSETID_FROM_TOKEN(n) id ##n = TOKEN2ATTRSETID(t ##n)
#define RUBY_INTERNAL_H 1
#define LIKELY(x) RB_LIKELY(x)
#define UNLIKELY(x) RB_UNLIKELY(x)
#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
#define roomof(x,y) (((x) + (y) - 1) / (y))
#define type_roomof(x,y) roomof(sizeof(x), sizeof(y))
#define ACCESS_ONCE(type,x) (*((volatile type *)&(x)))
#define UNDEF_P RB_UNDEF_P
#define NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
#undef RARRAY_AREF
#undef RClass
#undef RCLASS_SUPER
#undef NEWOBJ_OF
#undef RB_NEWOBJ_OF
#undef RB_OBJ_WRITE
#undef RHASH_IFNONE
#undef RHASH_SIZE
#undef RHASH_TBL
#undef RHASH_EMPTY_P
#undef RSTRUCT_LEN
#undef RSTRUCT_PTR
#undef RSTRUCT_SET
#undef RSTRUCT_GET
#define rb_ary_new_from_args(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_io_fptr_finalize(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_fstring_cstr(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_sym_intern_ascii_cstr(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_funcallv(...) rb_nonexistent_symbol(__VA_ARGS__)
#define rb_method_basic_definition_p(...) rb_nonexistent_symbol(__VA_ARGS__)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rp(obj) rb_obj_info_dump_loc((VALUE)(obj), __FILE__, __LINE__, RUBY_FUNCTION_NAME_STRING)
#define rp_m(msg,obj) do { fputs((msg), stderr); rb_obj_info_dump((VALUE)(obj)); } while (0)
#define bp() ruby_debug_breakpoint()
#define RBOOL(v) ((v) ? Qtrue : Qfalse)
#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
#undef memcpy
#define memcpy ruby_nonempty_memcpy
#define INTERNAL_ARRAY_H
#define INTERNAL_STATIC_ASSERT_H
#define STATIC_ASSERT RBIMPL_STATIC_ASSERT
#define ARRAY_DEBUG (0+RUBY_DEBUG)
#define RARRAY_SHARED_FLAG ELTS_SHARED
#define RARRAY_SHARED_ROOT_FLAG FL_USER12
#define RARRAY_PTR_IN_USE_FLAG FL_USER14
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#undef rb_ary_new_from_args
#define rb_ary_new_from_args(n,...) __extension__ ({ const VALUE args_to_new_ary[] = {__VA_ARGS__}; if (__builtin_constant_p(n)) { STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); } rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); })
#undef RARRAY_AREF
#define INTERNAL_BOP_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
#define STRING_REDEFINED_OP_FLAG (1 << 2)
#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
#define HASH_REDEFINED_OP_FLAG (1 << 4)
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7)
#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
#define NIL_REDEFINED_OP_FLAG (1 << 9)
#define TRUE_REDEFINED_OP_FLAG (1 << 10)
#define FALSE_REDEFINED_OP_FLAG (1 << 11)
#define PROC_REDEFINED_OP_FLAG (1 << 12)
#define BASIC_OP_UNREDEFINED_P(op,klass) (LIKELY((ruby_vm_redefined_flag[(op)]&(klass)) == 0))
#define INTERNAL_SERIAL_H
#define SERIALT2NUM ULL2NUM
#define PRI_SERIALT_PREFIX PRI_LL_PREFIX
#define SIZEOF_SERIAL_T SIZEOF_LONG_LONG
#define INTERNAL_VM_H
#undef rb_funcallv
#undef rb_method_basic_definition_p
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_DTRACE_CREATE_HOOK(name,arg) RUBY_DTRACE_HOOK(name ##_CREATE, arg)
#define RUBY_DTRACE_HOOK(name,arg) do { if (UNLIKELY(RUBY_DTRACE_ ##name ##_ENABLED())) { int dtrace_line; const char *dtrace_file = rb_source_location_cstr(&dtrace_line); if (!dtrace_file) dtrace_file = ""; RUBY_DTRACE_ ##name(arg, dtrace_file, dtrace_line); } } while (0)
#define RUBY_METHOD_H 1
#define INTERNAL_IMEMO_H
#define INTERNAL_GC_H
#define INTERNAL_COMPILERS_H
#define RUBY_BACKWARD2_GCC_VERSION_SINCE_H
#define GCC_VERSION_SINCE(x,y,z) RBIMPL_COMPILER_SINCE(GCC, (x), (y), (z))
#define GCC_VERSION_BEFORE(x,y,z) (RBIMPL_COMPILER_BEFORE(GCC, (x), (y), (z)) || (RBIMPL_COMPILER_IS(GCC) && ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && (RBIMPL_COMPILER_VERSION_PATCH == (z))))))
#define MSC_VERSION_SINCE(_) RBIMPL_COMPILER_SINCE(MSVC, (_) / 100, (_) % 100, 0)
#define MSC_VERSION_BEFORE(_) RBIMPL_COMPILER_BEFORE(MSVC, (_) / 100, (_) % 100, 0)
#define __has_c_attribute(...) 0
#define __has_declspec_attribute(...) RBIMPL_HAS_DECLSPEC_ATTRIBUTE(__VA_ARGS__)
#define __has_builtin(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__)
#define __has_feature(...) RBIMPL_HAS_FEATURE(__VA_ARGS__)
#define __has_extension(...) RBIMPL_HAS_EXTENSION(__VA_ARGS__)
#define __has_warning(...) RBIMPL_HAS_WARNING(__VA_ARGS__)
#define RB_OBJ_BUILTIN_TYPE(obj) rb_obj_builtin_type(obj)
#define OBJ_BUILTIN_TYPE(obj) RB_OBJ_BUILTIN_TYPE(obj)
#define rb_obj_builtin_type(obj) __extension__({ VALUE arg_obj = (obj); RB_SPECIAL_CONST_P(arg_obj) ? -1 : (int)RB_BUILTIN_TYPE(arg_obj); })
#define FLEX_ARY_LEN
#define BITFIELD(type,name,size) type name : size
#define RVALUE_SIZE (sizeof(struct RBasic) + sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]))
#define RB_RVARGC_NEWOBJ_OF(var,T,c,f,s) T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? rb_wb_protected_newobj_of((c), (f) & ~FL_WB_PROTECTED, s) : rb_wb_unprotected_newobj_of((c), (f), s))
#define RB_RVARGC_EC_NEWOBJ_OF(ec,var,T,c,f,s) T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? rb_ec_wb_protected_newobj_of((ec), (c), (f) & ~FL_WB_PROTECTED, s) : rb_wb_unprotected_newobj_of((c), (f), s))
#define RB_NEWOBJ_OF(var,T,c,f) RB_RVARGC_NEWOBJ_OF(var, T, c, f, RVALUE_SIZE)
#define RB_EC_NEWOBJ_OF(ec,var,T,c,f) RB_RVARGC_EC_NEWOBJ_OF(ec, var, T, c, f, RVALUE_SIZE)
#define NEWOBJ_OF(var,T,c,f) RB_NEWOBJ_OF((var), T, (c), (f))
#define RVARGC_NEWOBJ_OF(var,T,c,f,s) RB_RVARGC_NEWOBJ_OF((var), T, (c), (f), (s))
#define RB_OBJ_GC_FLAGS_MAX 6
#define UNALIGNED_MEMBER_ACCESS(expr) (expr)
#define UNALIGNED_MEMBER_PTR(ptr,mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
#define RB_OBJ_WRITE(a,slot,b) rb_obj_write((VALUE)(a), UNALIGNED_MEMBER_ACCESS((VALUE *)(slot)), (VALUE)(b), __FILE__, __LINE__)
#define SIZE_POOL_COUNT 5
#define RCLASS_EXT_EMBEDDED (SIZE_POOL_COUNT > 1)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define SIZED_REALLOC_N(x,y,z,w) REALLOC_N(x, y, z)
#define ruby_sized_xrealloc ruby_sized_xrealloc_inlined
#define ruby_sized_xrealloc2 ruby_sized_xrealloc2_inlined
#define ruby_sized_xfree ruby_sized_xfree_inlined
#define IMEMO_DEBUG 0
#define IMEMO_MASK 0x0f
#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
#define IMEMO_FL_USER0 FL_USER4
#define IMEMO_FL_USER1 FL_USER5
#define IMEMO_FL_USER2 FL_USER6
#define IMEMO_FL_USER3 FL_USER7
#define IMEMO_FL_USER4 FL_USER8
#define IMEMO_FL_USER5 FL_USER9
#define THROW_DATA_CONSUMED IMEMO_FL_USER0
#define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
#define MEMO_CAST(m) ((struct MEMO *)(m))
#define MEMO_NEW(a,b,c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
#define MEMO_FOR(type,value) ((type *)RARRAY_PTR(value))
#define NEW_MEMO_FOR(type,value) ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
#define NEW_PARTIAL_MEMO_FOR(type,value,member) ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), MEMO_FOR(type, value))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define IMEMO_TYPE_P(v,t) imemo_type_p((VALUE)v, t)
#define END_OF_ENUMERATION(key)
#define METHOD_ENTRY_VISI(me) (rb_method_visibility_t)(((me)->flags & (IMEMO_FL_USER0 | IMEMO_FL_USER1)) >> (IMEMO_FL_USHIFT+0))
#define METHOD_ENTRY_BASIC(me) (int) (((me)->flags & (IMEMO_FL_USER2 )) >> (IMEMO_FL_USHIFT+2))
#define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3)
#define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags |= IMEMO_FL_USER3)
#define METHOD_ENTRY_CACHED(me) ((me)->flags & IMEMO_FL_USER4)
#define METHOD_ENTRY_CACHED_SET(me) ((me)->flags |= IMEMO_FL_USER4)
#define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5)
#define METHOD_ENTRY_INVALIDATED_SET(me) ((me)->flags |= IMEMO_FL_USER5)
#define VM_METHOD_TYPE_MINIMUM_BITS 4
#define rb_iseq_t rb_iseq_t
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
#define UNDEFINED_REFINED_METHOD_P(def) ((def)->type == VM_METHOD_TYPE_REFINED && UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_NODE_H 1
#define RNODE(obj) ((struct RNode *)(obj))
#define NODE_FL_NEWLINE (((VALUE)1)<<7)
#define NODE_TYPESHIFT 8
#define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
#define nd_type(n) ((int) (((n)->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
#define nd_set_type(n,t) rb_node_set_type(n, t)
#define nd_init_type(n,t) (n)->flags=(((n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
#define NODE_LSHIFT (NODE_TYPESHIFT+7)
#define NODE_LMASK (((SIGNED_VALUE)1<<(sizeof(VALUE)*CHAR_BIT-NODE_LSHIFT))-1)
#define nd_line(n) (int)(((SIGNED_VALUE)(n)->flags)>>NODE_LSHIFT)
#define nd_set_line(n,l) (n)->flags=(((n)->flags&~((VALUE)(-1)<<NODE_LSHIFT))|((VALUE)((l)&NODE_LMASK)<<NODE_LSHIFT))
#define nd_first_column(n) ((int)((n)->nd_loc.beg_pos.column))
#define nd_set_first_column(n,v) ((n)->nd_loc.beg_pos.column = (v))
#define nd_first_lineno(n) ((int)((n)->nd_loc.beg_pos.lineno))
#define nd_set_first_lineno(n,v) ((n)->nd_loc.beg_pos.lineno = (v))
#define nd_first_loc(n) ((n)->nd_loc.beg_pos)
#define nd_set_first_loc(n,v) (nd_first_loc(n) = (v))
#define nd_last_column(n) ((int)((n)->nd_loc.end_pos.column))
#define nd_set_last_column(n,v) ((n)->nd_loc.end_pos.column = (v))
#define nd_last_lineno(n) ((int)((n)->nd_loc.end_pos.lineno))
#define nd_set_last_lineno(n,v) ((n)->nd_loc.end_pos.lineno = (v))
#define nd_last_loc(n) ((n)->nd_loc.end_pos)
#define nd_set_last_loc(n,v) (nd_last_loc(n) = (v))
#define nd_node_id(n) ((n)->node_id)
#define nd_set_node_id(n,id) ((n)->node_id = (id))
#define nd_head u1.node
#define nd_alen u2.argc
#define nd_next u3.node
#define nd_cond u1.node
#define nd_body u2.node
#define nd_else u3.node
#define nd_resq u2.node
#define nd_ensr u3.node
#define nd_1st u1.node
#define nd_2nd u2.node
#define nd_stts u1.node
#define nd_entry u3.id
#define nd_vid u1.id
#define nd_var u1.node
#define nd_iter u3.node
#define nd_value u2.node
#define nd_aid u3.id
#define nd_lit u1.value
#define nd_recv u1.node
#define nd_mid u2.id
#define nd_args u3.node
#define nd_ainfo u3.args
#define nd_defn u3.node
#define nd_cpath u1.node
#define nd_super u3.node
#define nd_beg u1.node
#define nd_end u2.node
#define nd_state u3.state
#define nd_nth u2.argc
#define nd_alias u1.id
#define nd_orig u2.id
#define nd_undef u2.node
#define nd_brace u2.argc
#define nd_pconst u1.node
#define nd_pkwargs u2.node
#define nd_pkwrestarg u3.node
#define nd_apinfo u3.apinfo
#define nd_fpinfo u3.fpinfo
#define nd_tbl u1.tbl
#define nd_pid u1.id
#define nd_plen u2.argc
#define nd_cflag u2.id
#define nd_cval u3.value
#define nd_rval u2.value
#define nd_tag u1.id
#define NEW_NODE(t,a0,a1,a2,loc) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2),loc)
#define NEW_NODE_WITH_LOCALS(t,a1,a2,loc) node_newnode_with_locals(p, (t),(VALUE)(a1),(VALUE)(a2),loc)
#define NEW_DEFN(i,a,d,loc) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d,loc),loc)
#define NEW_DEFS(r,i,a,d,loc) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d,loc),loc)
#define NEW_SCOPE(a,b,loc) NEW_NODE_WITH_LOCALS(NODE_SCOPE,b,a,loc)
#define NEW_BLOCK(a,loc) NEW_NODE(NODE_BLOCK,a,0,0,loc)
#define NEW_IF(c,t,e,loc) NEW_NODE(NODE_IF,c,t,e,loc)
#define NEW_UNLESS(c,t,e,loc) NEW_NODE(NODE_UNLESS,c,t,e,loc)
#define NEW_CASE(h,b,loc) NEW_NODE(NODE_CASE,h,b,0,loc)
#define NEW_CASE2(b,loc) NEW_NODE(NODE_CASE2,0,b,0,loc)
#define NEW_CASE3(h,b,loc) NEW_NODE(NODE_CASE3,h,b,0,loc)
#define NEW_WHEN(c,t,e,loc) NEW_NODE(NODE_WHEN,c,t,e,loc)
#define NEW_IN(c,t,e,loc) NEW_NODE(NODE_IN,c,t,e,loc)
#define NEW_WHILE(c,b,n,loc) NEW_NODE(NODE_WHILE,c,b,n,loc)
#define NEW_UNTIL(c,b,n,loc) NEW_NODE(NODE_UNTIL,c,b,n,loc)
#define NEW_FOR(i,b,loc) NEW_NODE(NODE_FOR,0,b,i,loc)
#define NEW_FOR_MASGN(v,loc) NEW_NODE(NODE_FOR_MASGN,v,0,0,loc)
#define NEW_ITER(a,b,loc) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b,loc),0,loc)
#define NEW_LAMBDA(a,b,loc) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b,loc),0,loc)
#define NEW_BREAK(s,loc) NEW_NODE(NODE_BREAK,s,0,0,loc)
#define NEW_NEXT(s,loc) NEW_NODE(NODE_NEXT,s,0,0,loc)
#define NEW_REDO(loc) NEW_NODE(NODE_REDO,0,0,0,loc)
#define NEW_RETRY(loc) NEW_NODE(NODE_RETRY,0,0,0,loc)
#define NEW_BEGIN(b,loc) NEW_NODE(NODE_BEGIN,0,b,0,loc)
#define NEW_RESCUE(b,res,e,loc) NEW_NODE(NODE_RESCUE,b,res,e,loc)
#define NEW_RESBODY(a,ex,n,loc) NEW_NODE(NODE_RESBODY,n,ex,a,loc)
#define NEW_ENSURE(b,en,loc) NEW_NODE(NODE_ENSURE,b,0,en,loc)
#define NEW_RETURN(s,loc) NEW_NODE(NODE_RETURN,s,0,0,loc)
#define NEW_YIELD(a,loc) NEW_NODE(NODE_YIELD,a,0,0,loc)
#define NEW_LIST(a,loc) NEW_NODE(NODE_LIST,a,1,0,loc)
#define NEW_ZLIST(loc) NEW_NODE(NODE_ZLIST,0,0,0,loc)
#define NEW_HASH(a,loc) NEW_NODE(NODE_HASH,a,0,0,loc)
#define NEW_MASGN(l,r,loc) NEW_NODE(NODE_MASGN,l,0,r,loc)
#define NEW_GASGN(v,val,loc) NEW_NODE(NODE_GASGN,v,val,v,loc)
#define NEW_LASGN(v,val,loc) NEW_NODE(NODE_LASGN,v,val,0,loc)
#define NEW_DASGN(v,val,loc) NEW_NODE(NODE_DASGN,v,val,0,loc)
#define NEW_IASGN(v,val,loc) NEW_NODE(NODE_IASGN,v,val,0,loc)
#define NEW_CDECL(v,val,path,loc) NEW_NODE(NODE_CDECL,v,val,path,loc)
#define NEW_CVASGN(v,val,loc) NEW_NODE(NODE_CVASGN,v,val,0,loc)
#define NEW_OP_ASGN1(p,id,a,loc) NEW_NODE(NODE_OP_ASGN1,p,id,a,loc)
#define NEW_OP_ASGN2(r,t,i,o,val,loc) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o,t,loc),loc)
#define NEW_OP_ASGN22(i,o,t,loc) NEW_NODE(NODE_OP_ASGN2,i,o,t,loc)
#define NEW_OP_ASGN_OR(i,val,loc) NEW_NODE(NODE_OP_ASGN_OR,i,val,0,loc)
#define NEW_OP_ASGN_AND(i,val,loc) NEW_NODE(NODE_OP_ASGN_AND,i,val,0,loc)
#define NEW_OP_CDECL(v,op,val,loc) NEW_NODE(NODE_OP_CDECL,v,val,op,loc)
#define NEW_GVAR(v,loc) NEW_NODE(NODE_GVAR,v,0,v,loc)
#define NEW_LVAR(v,loc) NEW_NODE(NODE_LVAR,v,0,0,loc)
#define NEW_DVAR(v,loc) NEW_NODE(NODE_DVAR,v,0,0,loc)
#define NEW_IVAR(v,loc) NEW_NODE(NODE_IVAR,v,0,0,loc)
#define NEW_CONST(v,loc) NEW_NODE(NODE_CONST,v,0,0,loc)
#define NEW_CVAR(v,loc) NEW_NODE(NODE_CVAR,v,0,0,loc)
#define NEW_NTH_REF(n,loc) NEW_NODE(NODE_NTH_REF,0,n,0,loc)
#define NEW_BACK_REF(n,loc) NEW_NODE(NODE_BACK_REF,0,n,0,loc)
#define NEW_MATCH(c,loc) NEW_NODE(NODE_MATCH,c,0,0,loc)
#define NEW_MATCH2(n1,n2,loc) NEW_NODE(NODE_MATCH2,n1,n2,0,loc)
#define NEW_MATCH3(r,n2,loc) NEW_NODE(NODE_MATCH3,r,n2,0,loc)
#define NEW_LIT(l,loc) NEW_NODE(NODE_LIT,l,0,0,loc)
#define NEW_STR(s,loc) NEW_NODE(NODE_STR,s,0,0,loc)
#define NEW_DSTR(s,loc) NEW_NODE(NODE_DSTR,s,1,0,loc)
#define NEW_XSTR(s,loc) NEW_NODE(NODE_XSTR,s,0,0,loc)
#define NEW_DXSTR(s,loc) NEW_NODE(NODE_DXSTR,s,0,0,loc)
#define NEW_DSYM(s,loc) NEW_NODE(NODE_DSYM,s,0,0,loc)
#define NEW_EVSTR(n,loc) NEW_NODE(NODE_EVSTR,0,(n),0,loc)
#define NEW_CALL(r,m,a,loc) NEW_NODE(NODE_CALL,r,m,a,loc)
#define NEW_OPCALL(r,m,a,loc) NEW_NODE(NODE_OPCALL,r,m,a,loc)
#define NEW_FCALL(m,a,loc) NEW_NODE(NODE_FCALL,0,m,a,loc)
#define NEW_VCALL(m,loc) NEW_NODE(NODE_VCALL,0,m,0,loc)
#define NEW_SUPER(a,loc) NEW_NODE(NODE_SUPER,0,0,a,loc)
#define NEW_ZSUPER(loc) NEW_NODE(NODE_ZSUPER,0,0,0,loc)
#define NEW_ARGS_AUX(r,b,loc) NEW_NODE(NODE_ARGS_AUX,r,b,0,loc)
#define NEW_OPT_ARG(i,v,loc) NEW_NODE(NODE_OPT_ARG,i,v,0,loc)
#define NEW_KW_ARG(i,v,loc) NEW_NODE(NODE_KW_ARG,i,v,0,loc)
#define NEW_POSTARG(i,v,loc) NEW_NODE(NODE_POSTARG,i,v,0,loc)
#define NEW_ARGSCAT(a,b,loc) NEW_NODE(NODE_ARGSCAT,a,b,0,loc)
#define NEW_ARGSPUSH(a,b,loc) NEW_NODE(NODE_ARGSPUSH,a,b,0,loc)
#define NEW_SPLAT(a,loc) NEW_NODE(NODE_SPLAT,a,0,0,loc)
#define NEW_BLOCK_PASS(b,loc) NEW_NODE(NODE_BLOCK_PASS,0,b,0,loc)
#define NEW_ALIAS(n,o,loc) NEW_NODE(NODE_ALIAS,n,o,0,loc)
#define NEW_VALIAS(n,o,loc) NEW_NODE(NODE_VALIAS,n,o,0,loc)
#define NEW_UNDEF(i,loc) NEW_NODE(NODE_UNDEF,0,i,0,loc)
#define NEW_CLASS(n,b,s,loc) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(0,b,loc),(s),loc)
#define NEW_SCLASS(r,b,loc) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b,loc),0,loc)
#define NEW_MODULE(n,b,loc) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b,loc),0,loc)
#define NEW_COLON2(c,i,loc) NEW_NODE(NODE_COLON2,c,i,0,loc)
#define NEW_COLON3(i,loc) NEW_NODE(NODE_COLON3,0,i,0,loc)
#define NEW_DOT2(b,e,loc) NEW_NODE(NODE_DOT2,b,e,0,loc)
#define NEW_DOT3(b,e,loc) NEW_NODE(NODE_DOT3,b,e,0,loc)
#define NEW_SELF(loc) NEW_NODE(NODE_SELF,0,0,1,loc)
#define NEW_NIL(loc) NEW_NODE(NODE_NIL,0,0,0,loc)
#define NEW_TRUE(loc) NEW_NODE(NODE_TRUE,0,0,0,loc)
#define NEW_FALSE(loc) NEW_NODE(NODE_FALSE,0,0,0,loc)
#define NEW_ERRINFO(loc) NEW_NODE(NODE_ERRINFO,0,0,0,loc)
#define NEW_DEFINED(e,loc) NEW_NODE(NODE_DEFINED,e,0,0,loc)
#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
#define NEW_ERROR(loc) NEW_NODE(NODE_ERROR,0,0,0,loc)
#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
#define NODE_SPECIAL_NO_NAME_REST ((NODE *)-1)
#define NODE_NAMED_REST_P(node) ((node) != NODE_SPECIAL_NO_NAME_REST)
#define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1)
#define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_ATOMIC_H
#define RUBY_ATOMIC_GENERIC_MACRO 1
#define RUBY_ATOMIC_FETCH_ADD(var,val) rbimpl_atomic_fetch_add(&(var), (val))
#define RUBY_ATOMIC_FETCH_SUB(var,val) rbimpl_atomic_fetch_sub(&(var), (val))
#define RUBY_ATOMIC_OR(var,val) rbimpl_atomic_or(&(var), (val))
#define RUBY_ATOMIC_EXCHANGE(var,val) rbimpl_atomic_exchange(&(var), (val))
#define RUBY_ATOMIC_CAS(var,oldval,newval) rbimpl_atomic_cas(&(var), (oldval), (newval))
#define RUBY_ATOMIC_SET(var,val) rbimpl_atomic_set(&(var), (val))
#define RUBY_ATOMIC_ADD(var,val) rbimpl_atomic_add(&(var), (val))
#define RUBY_ATOMIC_SUB(var,val) rbimpl_atomic_sub(&(var), (val))
#define RUBY_ATOMIC_INC(var) rbimpl_atomic_inc(&(var))
#define RUBY_ATOMIC_DEC(var) rbimpl_atomic_dec(&(var))
#define RUBY_ATOMIC_SIZE_INC(var) rbimpl_atomic_size_inc(&(var))
#define RUBY_ATOMIC_SIZE_DEC(var) rbimpl_atomic_size_dec(&(var))
#define RUBY_ATOMIC_SIZE_EXCHANGE(var,val) rbimpl_atomic_size_exchange(&(var), (val))
#define RUBY_ATOMIC_SIZE_CAS(var,oldval,newval) rbimpl_atomic_size_cas(&(var), (oldval), (newval))
#define RUBY_ATOMIC_SIZE_ADD(var,val) rbimpl_atomic_size_add(&(var), (val))
#define RUBY_ATOMIC_SIZE_SUB(var,val) rbimpl_atomic_size_sub(&(var), (val))
#define RUBY_ATOMIC_PTR_EXCHANGE(var,val) RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))
#define RUBY_ATOMIC_PTR_CAS(var,oldval,newval) RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (oldval), (newval)))
#define RUBY_ATOMIC_VALUE_EXCHANGE(var,val) rbimpl_atomic_value_exchange(&(var), (val))
#define RUBY_ATOMIC_VALUE_CAS(var,oldval,newval) rbimpl_atomic_value_cas(&(var), (oldval), (newval))
#define ATOMIC_ADD(var,val) RUBY_ATOMIC_ADD(var, val)
#define ATOMIC_CAS(var,oldval,newval) RUBY_ATOMIC_CAS(var, oldval, newval)
#define ATOMIC_DEC(var) RUBY_ATOMIC_DEC(var)
#define ATOMIC_EXCHANGE(var,val) RUBY_ATOMIC_EXCHANGE(var, val)
#define ATOMIC_FETCH_ADD(var,val) RUBY_ATOMIC_FETCH_ADD(var, val)
#define ATOMIC_FETCH_SUB(var,val) RUBY_ATOMIC_FETCH_SUB(var, val)
#define ATOMIC_INC(var) RUBY_ATOMIC_INC(var)
#define ATOMIC_OR(var,val) RUBY_ATOMIC_OR(var, val)
#define ATOMIC_PTR_CAS(var,oldval,newval) RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
#define ATOMIC_PTR_EXCHANGE(var,val) RUBY_ATOMIC_PTR_EXCHANGE(var, val)
#define ATOMIC_SET(var,val) RUBY_ATOMIC_SET(var, val)
#define ATOMIC_SIZE_ADD(var,val) RUBY_ATOMIC_SIZE_ADD(var, val)
#define ATOMIC_SIZE_CAS(var,oldval,newval) RUBY_ATOMIC_SIZE_CAS(var, oldval, newval)
#define ATOMIC_SIZE_DEC(var) RUBY_ATOMIC_SIZE_DEC(var)
#define ATOMIC_SIZE_EXCHANGE(var,val) RUBY_ATOMIC_SIZE_EXCHANGE(var, val)
#define ATOMIC_SIZE_INC(var) RUBY_ATOMIC_SIZE_INC(var)
#define ATOMIC_SIZE_SUB(var,val) RUBY_ATOMIC_SIZE_SUB(var, val)
#define ATOMIC_SUB(var,val) RUBY_ATOMIC_SUB(var, val)
#define ATOMIC_VALUE_CAS(var,oldval,val) RUBY_ATOMIC_VALUE_CAS(var, oldval, val)
#define ATOMIC_VALUE_EXCHANGE(var,val) RUBY_ATOMIC_VALUE_EXCHANGE(var, val)
#define RUBY_VM_OPTS_H
#define OPT_TAILCALL_OPTIMIZATION 0
#define OPT_PEEPHOLE_OPTIMIZATION 1
#define OPT_SPECIALISED_INSTRUCTION 1
#define OPT_INLINE_CONST_CACHE 1
#define OPT_FROZEN_STRING_LITERAL 0
#define OPT_DEBUG_FROZEN_STRING_LITERAL 0
#define OPT_THREADED_CODE 0
#define OPT_DIRECT_THREADED_CODE (OPT_THREADED_CODE == 0)
#define OPT_TOKEN_THREADED_CODE (OPT_THREADED_CODE == 1)
#define OPT_CALL_THREADED_CODE (OPT_THREADED_CODE == 2)
#define OPT_CHECKED_RUN 1
#define OPT_INLINE_METHOD_CACHE 1
#define OPT_GLOBAL_METHOD_CACHE 1
#define OPT_BLOCKINLINING 0
#define OPT_IC_FOR_IVAR 1
#define OPT_OPERANDS_UNIFICATION 1
#define OPT_INSTRUCTIONS_UNIFICATION 0
#define OPT_UNIFY_ALL_COMBINATION 0
#define OPT_STACK_CACHING 0
#define OPT_SUPPORT_JOKE 0
#define OPT_SUPPORT_CALL_C_FUNCTION 0
#define VM_COLLECT_USAGE_DETAILS 0
#define RUBY_SHAPE_H
#define SIZEOF_SHAPE_T 4
#define SHAPE_IN_BASIC_FLAGS 1
#define MAX_IVARS (attr_index_t)(-1)
#define SHAPE_ID_NUM_BITS 32
#define SHAPE_MASK (((uintptr_t)1 << SHAPE_ID_NUM_BITS) - 1)
#define SHAPE_FLAG_MASK (((VALUE)-1) >> SHAPE_ID_NUM_BITS)
#define SHAPE_FLAG_SHIFT ((SIZEOF_VALUE * 8) - SHAPE_ID_NUM_BITS)
#define SHAPE_BITMAP_SIZE 16384
#define SHAPE_MAX_VARIATIONS 8
#define MAX_SHAPE_ID (SHAPE_MASK - 1)
#define INVALID_SHAPE_ID SHAPE_MASK
#define ROOT_SHAPE_ID 0x0
#define SPECIAL_CONST_SHAPE_ID (SIZE_POOL_COUNT * 2)
#define OBJ_TOO_COMPLEX_SHAPE_ID (SPECIAL_CONST_SHAPE_ID + 1)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_THREAD_NATIVE_H 1
#define _PTHREAD_H 1
#define _SCHED_H 1
#define __need_size_t
#define __need_NULL
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define _BITS_SCHED_H 1
#define SCHED_OTHER 0
#define SCHED_FIFO 1
#define SCHED_RR 2
#define SCHED_BATCH 3
#define SCHED_ISO 4
#define SCHED_IDLE 5
#define SCHED_DEADLINE 6
#define SCHED_RESET_ON_FORK 0x40000000
#define CSIGNAL 0x000000ff
#define CLONE_VM 0x00000100
#define CLONE_FS 0x00000200
#define CLONE_FILES 0x00000400
#define CLONE_SIGHAND 0x00000800
#define CLONE_PTRACE 0x00002000
#define CLONE_VFORK 0x00004000
#define CLONE_PARENT 0x00008000
#define CLONE_THREAD 0x00010000
#define CLONE_NEWNS 0x00020000
#define CLONE_SYSVSEM 0x00040000
#define CLONE_SETTLS 0x00080000
#define CLONE_PARENT_SETTID 0x00100000
#define CLONE_CHILD_CLEARTID 0x00200000
#define CLONE_DETACHED 0x00400000
#define CLONE_UNTRACED 0x00800000
#define CLONE_CHILD_SETTID 0x01000000
#define CLONE_NEWCGROUP 0x02000000
#define CLONE_NEWUTS 0x04000000
#define CLONE_NEWIPC 0x08000000
#define CLONE_NEWUSER 0x10000000
#define CLONE_NEWPID 0x20000000
#define CLONE_NEWNET 0x40000000
#define CLONE_IO 0x80000000
#define _BITS_TYPES_STRUCT_SCHED_PARAM 1
#define _BITS_CPU_SET_H 1
#define __CPU_SETSIZE 1024
#define __NCPUBITS (8 * sizeof (__cpu_mask))
#define __CPUELT(cpu) ((cpu) / __NCPUBITS)
#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
#define __CPU_ZERO_S(setsize,cpusetp) do __builtin_memset (cpusetp, '\0', setsize); while (0)
#define __CPU_SET_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (setsize) ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] |= __CPUMASK (__cpu)) : 0; }))
#define __CPU_CLR_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (setsize) ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] &= ~__CPUMASK (__cpu)) : 0; }))
#define __CPU_ISSET_S(cpu,setsize,cpusetp) (__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (setsize) ? ((((const __cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] & __CPUMASK (__cpu))) != 0 : 0; }))
#define __CPU_COUNT_S(setsize,cpusetp) __sched_cpucount (setsize, cpusetp)
#define __CPU_EQUAL_S(setsize,cpusetp1,cpusetp2) (__builtin_memcmp (cpusetp1, cpusetp2, setsize) == 0)
#define __CPU_OP_S(setsize,destset,srcset1,srcset2,op) (__extension__ ({ cpu_set_t *__dest = (destset); const __cpu_mask *__arr1 = (srcset1)->__bits; const __cpu_mask *__arr2 = (srcset2)->__bits; size_t __imax = (setsize) / sizeof (__cpu_mask); size_t __i; for (__i = 0; __i < __imax; ++__i) ((__cpu_mask *) __dest->__bits)[__i] = __arr1[__i] op __arr2[__i]; __dest; }))
#define __CPU_ALLOC_SIZE(count) ((((count) + __NCPUBITS - 1) / __NCPUBITS) * sizeof (__cpu_mask))
#define __CPU_ALLOC(count) __sched_cpualloc (count)
#define __CPU_FREE(cpuset) __sched_cpufree (cpuset)
#define sched_priority sched_priority
#define __sched_priority sched_priority
#define CPU_SETSIZE __CPU_SETSIZE
#define CPU_SET(cpu,cpusetp) __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp)
#define CPU_CLR(cpu,cpusetp) __CPU_CLR_S (cpu, sizeof (cpu_set_t), cpusetp)
#define CPU_ISSET(cpu,cpusetp) __CPU_ISSET_S (cpu, sizeof (cpu_set_t), cpusetp)
#define CPU_ZERO(cpusetp) __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp)
#define CPU_COUNT(cpusetp) __CPU_COUNT_S (sizeof (cpu_set_t), cpusetp)
#define CPU_SET_S(cpu,setsize,cpusetp) __CPU_SET_S (cpu, setsize, cpusetp)
#define CPU_CLR_S(cpu,setsize,cpusetp) __CPU_CLR_S (cpu, setsize, cpusetp)
#define CPU_ISSET_S(cpu,setsize,cpusetp) __CPU_ISSET_S (cpu, setsize, cpusetp)
#define CPU_ZERO_S(setsize,cpusetp) __CPU_ZERO_S (setsize, cpusetp)
#define CPU_COUNT_S(setsize,cpusetp) __CPU_COUNT_S (setsize, cpusetp)
#define CPU_EQUAL(cpusetp1,cpusetp2) __CPU_EQUAL_S (sizeof (cpu_set_t), cpusetp1, cpusetp2)
#define CPU_EQUAL_S(setsize,cpusetp1,cpusetp2) __CPU_EQUAL_S (setsize, cpusetp1, cpusetp2)
#define CPU_AND(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, &)
#define CPU_OR(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, |)
#define CPU_XOR(destset,srcset1,srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, ^)
#define CPU_AND_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, &)
#define CPU_OR_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, |)
#define CPU_XOR_S(setsize,destset,srcset1,srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, ^)
#define CPU_ALLOC_SIZE(count) __CPU_ALLOC_SIZE (count)
#define CPU_ALLOC(count) __CPU_ALLOC (count)
#define CPU_FREE(cpuset) __CPU_FREE (cpuset)
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __SYSCALL_WORDSIZE 64
#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
#define PTHREAD_MUTEX_INITIALIZER { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } }
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __PTHREAD_SPINS, { 0, 0 } } }
#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } }
#define PTHREAD_RWLOCK_INITIALIZER { { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, 0 } }
#define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP { { 0, 0, 0, 0, 0, 0, 0, 0, __PTHREAD_RWLOCK_ELISION_EXTRA, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
#define PTHREAD_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
#define PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
#define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
#define PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
#define PTHREAD_CANCELED ((void *) -1)
#define PTHREAD_ONCE_INIT 0
#define PTHREAD_BARRIER_SERIAL_THREAD -1
#define __cleanup_fct_attribute
#define pthread_cleanup_push(routine,arg) do { struct __pthread_cleanup_frame __clframe __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) = { .__cancel_routine = (routine), .__cancel_arg = (arg), .__do_it = 1 };
#define pthread_cleanup_pop(execute) __clframe.__do_it = (execute); } while (0)
#define pthread_cleanup_push_defer_np(routine,arg) do { struct __pthread_cleanup_frame __clframe __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) = { .__cancel_routine = (routine), .__cancel_arg = (arg), .__do_it = 1 }; (void) pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &__clframe.__cancel_type)
#define pthread_cleanup_pop_restore_np(execute) (void) pthread_setcanceltype (__clframe.__cancel_type, NULL); __clframe.__do_it = (execute); } while (0)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define VM_INSN_INFO_TABLE_IMPL 2
#define RUBY_NSIG NSIG
#define RUBY_SIGCHLD (SIGCLD)
#define SIGCHLD_LOSSY (0)
#define WAITPID_USE_SIGCHLD (RUBY_SIGCHLD || SIGCHLD_LOSSY)
#define USE_SIGALTSTACK
#define RB_ALTSTACK_INIT(var,altstack) var = rb_register_sigaltstack(altstack)
#define RB_ALTSTACK_FREE(var) free(var)
#define RB_ALTSTACK(var) var
#define RUBY_THREAD_PTHREAD_H
#define RB_NATIVETHREAD_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
#define RB_NATIVETHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#undef except
#undef try
#undef leave
#undef finally
#define RB_THREAD_LOCAL_SPECIFIER _Thread_local
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_VM_THREAD_MODEL 2
#define TAG_NONE RUBY_TAG_NONE
#define TAG_RETURN RUBY_TAG_RETURN
#define TAG_BREAK RUBY_TAG_BREAK
#define TAG_NEXT RUBY_TAG_NEXT
#define TAG_RETRY RUBY_TAG_RETRY
#define TAG_REDO RUBY_TAG_REDO
#define TAG_RAISE RUBY_TAG_RAISE
#define TAG_THROW RUBY_TAG_THROW
#define TAG_FATAL RUBY_TAG_FATAL
#define TAG_MASK RUBY_TAG_MASK
#define CoreDataFromValue(obj,type) (type*)DATA_PTR(obj)
#define GetCoreDataFromValue(obj,type,ptr) ((ptr) = CoreDataFromValue((obj), type))
#define PATHOBJ_PATH 0
#define PATHOBJ_REALPATH 1
#define ISEQ_IS_SIZE(body) (body->ic_size + body->ivc_size + body->ise_size + body->icvarc_size)
#define ISEQ_IS_IC_ENTRY(body,idx) (body->is_entries[(idx) + body->ise_size + body->icvarc_size + body->ivc_size].ic_cache);
#define ISEQ_BODY(iseq) ((iseq)->body)
#define USE_LAZY_LOAD 0
#define GetVMPtr(obj,ptr) GetCoreDataFromValue((obj), rb_vm_t, (ptr))
#define VM_GLOBAL_CC_CACHE_TABLE_SIZE 1023
#define RUBY_VM_SIZE_ALIGN 4096
#define RUBY_VM_THREAD_VM_STACK_SIZE ( 128 * 1024 * sizeof(VALUE))
#define RUBY_VM_THREAD_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE))
#define RUBY_VM_THREAD_MACHINE_STACK_SIZE ( 128 * 1024 * sizeof(VALUE))
#define RUBY_VM_THREAD_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE))
#define RUBY_VM_FIBER_VM_STACK_SIZE ( 16 * 1024 * sizeof(VALUE))
#define RUBY_VM_FIBER_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE))
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE ( 64 * 1024 * sizeof(VALUE))
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE))
#define VM_DEBUG_BP_CHECK 0
#define VM_DEBUG_VERIFY_METHOD_CACHE (VMDEBUG != 0)
#define rb_execution_context_t rb_execution_context_t
#define VM_CORE_H_EC_DEFINED 1
#define VM_DEFINECLASS_TYPE(x) ((rb_vm_defineclass_type_t)(x) & VM_DEFINECLASS_TYPE_MASK)
#define VM_DEFINECLASS_FLAG_SCOPED 0x08
#define VM_DEFINECLASS_FLAG_HAS_SUPERCLASS 0x10
#define VM_DEFINECLASS_SCOPED_P(x) ((x) & VM_DEFINECLASS_FLAG_SCOPED)
#define VM_DEFINECLASS_HAS_SUPERCLASS_P(x) ((x) & VM_DEFINECLASS_FLAG_HAS_SUPERCLASS)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define GetProcPtr(obj,ptr) GetCoreDataFromValue((obj), rb_proc_t, (ptr))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define GetBindingPtr(obj,ptr) GetCoreDataFromValue((obj), rb_binding_t, (ptr))
#define VM_CHECKMATCH_TYPE_MASK 0x03
#define VM_CHECKMATCH_ARRAY 0x04
#define FUNC_FASTCALL(x) x
#define VM_TAGGED_PTR_SET(p,tag) ((VALUE)(p) | (tag))
#define VM_TAGGED_PTR_REF(v,mask) ((void *)((v) & ~mask))
#define GC_GUARDED_PTR(p) VM_TAGGED_PTR_SET((p), 0x01)
#define GC_GUARDED_PTR_REF(p) VM_TAGGED_PTR_REF((p), 0x03)
#define GC_GUARDED_PTR_P(p) (((VALUE)(p)) & 0x01)
#define VM_ENV_DATA_SIZE ( 3)
#define VM_ENV_DATA_INDEX_ME_CREF (-2)
#define VM_ENV_DATA_INDEX_SPECVAL (-1)
#define VM_ENV_DATA_INDEX_FLAGS ( 0)
#define VM_ENV_DATA_INDEX_ENV ( 1)
#define VM_ENV_INDEX_LAST_LVAR (-VM_ENV_DATA_SIZE)
#define RUBYVM_CFUNC_FRAME_P(cfp) (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
#define VM_GUARDED_PREV_EP(ep) GC_GUARDED_PTR(ep)
#define VM_BLOCK_HANDLER_NONE 0
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) ((cfp)+1)
#define RUBY_VM_NEXT_CONTROL_FRAME(cfp) ((cfp)-1)
#define RUBY_VM_VALID_CONTROL_FRAME_P(cfp,ecfp) ((void *)(ecfp) > (void *)(cfp))
#define SDR() rb_vmdebug_stack_dump_raw(GET_EC(), GET_EC()->cfp)
#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_EC(), (cfp))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_vm_register_special_exception(sp,e,m) rb_vm_register_special_exception_str(sp, e, rb_usascii_str_new_static((m), (long)rb_strlen_lit(m)))
#define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack]
#define CHECK_VM_STACK_OVERFLOW0(cfp,sp,margin) do { STATIC_ASSERT(sizeof_sp, sizeof(*(sp)) == sizeof(VALUE)); STATIC_ASSERT(sizeof_cfp, sizeof(*(cfp)) == sizeof(rb_control_frame_t)); const struct rb_control_frame_struct *bound = (void *)&(sp)[(margin)]; if (UNLIKELY((cfp) <= &bound[1])) { vm_stackoverflow(); } } while (0)
#define CHECK_VM_STACK_OVERFLOW(cfp,margin) CHECK_VM_STACK_OVERFLOW0((cfp), (cfp)->sp, (margin))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define GET_VM() rb_current_vm()
#define GET_RACTOR() rb_current_ractor()
#define GET_THREAD() rb_current_thread()
#define GET_EC() rb_current_execution_context(true)
#define RUBY_VM_SET_TIMER_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TIMER_INTERRUPT_MASK)
#define RUBY_VM_SET_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, PENDING_INTERRUPT_MASK)
#define RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, POSTPONED_JOB_INTERRUPT_MASK)
#define RUBY_VM_SET_TRAP_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TRAP_INTERRUPT_MASK)
#define RUBY_VM_SET_TERMINATE_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TERMINATE_INTERRUPT_MASK)
#define RUBY_VM_SET_VM_BARRIER_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, VM_BARRIER_INTERRUPT_MASK)
#define RUBY_VM_INTERRUPTED(ec) ((ec)->interrupt_flag & ~(ec)->interrupt_mask & (PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK))
#define RUBY_VM_CHECK_INTS(ec) rb_vm_check_ints(ec)
#define EXEC_EVENT_HOOK_ORIG(ec_,hooks_,flag_,self_,id_,called_id_,klass_,data_,pop_p_) do { const rb_event_flag_t flag_arg_ = (flag_); rb_hook_list_t *hooks_arg_ = (hooks_); if (UNLIKELY((hooks_arg_)->events & (flag_arg_))) { rb_exec_event_hook_orig(ec_, hooks_arg_, flag_arg_, self_, id_, called_id_, klass_, data_, pop_p_); } } while (0)
#define EXEC_EVENT_HOOK(ec_,flag_,self_,id_,called_id_,klass_,data_) EXEC_EVENT_HOOK_ORIG(ec_, rb_ec_ractor_hooks(ec_), flag_, self_, id_, called_id_, klass_, data_, 0)
#define EXEC_EVENT_HOOK_AND_POP_FRAME(ec_,flag_,self_,id_,called_id_,klass_,data_) EXEC_EVENT_HOOK_ORIG(ec_, rb_ec_ractor_hooks(ec_), flag_, self_, id_, called_id_, klass_, data_, 1)
#pragma GCC visibility push(default)
#define RUBY_EVENT_COVERAGE_LINE 0x010000
#define RUBY_EVENT_COVERAGE_BRANCH 0x020000
#pragma GCC visibility pop
#define PASS_PASSED_BLOCK_HANDLER_EC(ec) pass_passed_block_handler(ec)
#define PASS_PASSED_BLOCK_HANDLER() pass_passed_block_handler(GET_EC())
#define ruby_setjmp(env) RUBY_SETJMP(env)
#define ruby_longjmp(env,val) RUBY_LONGJMP((env),(val))
#define _ERRNO_H 1
#define _BITS_ERRNO_H 1
#define _ASM_GENERIC_ERRNO_H
#define _ASM_GENERIC_ERRNO_BASE_H
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define EDEADLK 35
#define ENAMETOOLONG 36
#define ENOLCK 37
#define ENOSYS 38
#define ENOTEMPTY 39
#define ELOOP 40
#define EWOULDBLOCK EAGAIN
#define ENOMSG 42
#define EIDRM 43
#define ECHRNG 44
#define EL2NSYNC 45
#define EL3HLT 46
#define EL3RST 47
#define ELNRNG 48
#define EUNATCH 49
#define ENOCSI 50
#define EL2HLT 51
#define EBADE 52
#define EBADR 53
#define EXFULL 54
#define ENOANO 55
#define EBADRQC 56
#define EBADSLT 57
#define EDEADLOCK EDEADLK
#define EBFONT 59
#define ENOSTR 60
#define ENODATA 61
#define ETIME 62
#define ENOSR 63
#define ENONET 64
#define ENOPKG 65
#define EREMOTE 66
#define ENOLINK 67
#define EADV 68
#define ESRMNT 69
#define ECOMM 70
#define EPROTO 71
#define EMULTIHOP 72
#define EDOTDOT 73
#define EBADMSG 74
#define EOVERFLOW 75
#define ENOTUNIQ 76
#define EBADFD 77
#define EREMCHG 78
#define ELIBACC 79
#define ELIBBAD 80
#define ELIBSCN 81
#define ELIBMAX 82
#define ELIBEXEC 83
#define EILSEQ 84
#define ERESTART 85
#define ESTRPIPE 86
#define EUSERS 87
#define ENOTSOCK 88
#define EDESTADDRREQ 89
#define EMSGSIZE 90
#define EPROTOTYPE 91
#define ENOPROTOOPT 92
#define EPROTONOSUPPORT 93
#define ESOCKTNOSUPPORT 94
#define EOPNOTSUPP 95
#define EPFNOSUPPORT 96
#define EAFNOSUPPORT 97
#define EADDRINUSE 98
#define EADDRNOTAVAIL 99
#define ENETDOWN 100
#define ENETUNREACH 101
#define ENETRESET 102
#define ECONNABORTED 103
#define ECONNRESET 104
#define ENOBUFS 105
#define EISCONN 106
#define ENOTCONN 107
#define ESHUTDOWN 108
#define ETOOMANYREFS 109
#define ETIMEDOUT 110
#define ECONNREFUSED 111
#define EHOSTDOWN 112
#define EHOSTUNREACH 113
#define EALREADY 114
#define EINPROGRESS 115
#define ESTALE 116
#define EUCLEAN 117
#define ENOTNAM 118
#define ENAVAIL 119
#define EISNAM 120
#define EREMOTEIO 121
#define EDQUOT 122
#define ENOMEDIUM 123
#define EMEDIUMTYPE 124
#define ECANCELED 125
#define ENOKEY 126
#define EKEYEXPIRED 127
#define EKEYREVOKED 128
#define EKEYREJECTED 129
#define EOWNERDEAD 130
#define ENOTRECOVERABLE 131
#define ERFKILL 132
#define EHWPOISON 133
#define ENOTSUP EOPNOTSUPP
#define errno (*__errno_location ())
#define __error_t_defined 1
#define _SYS_PARAM_H 1
#define __need_NULL
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_wchar_t
#undef NULL
#define NULL ((void *)0)
#undef __need_NULL
#define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define __undef_ARG_MAX
#define _LINUX_PARAM_H
#define __ASM_GENERIC_PARAM_H
#define HZ 100
#define EXEC_PAGESIZE 4096
#define NOGROUP (-1)
#define MAXHOSTNAMELEN 64
#undef ARG_MAX
#undef __undef_ARG_MAX
#define MAXSYMLINKS 20
#define NOFILE 256
#define NCARGS 131072
#define NBBY CHAR_BIT
#define NGROUPS NGROUPS_MAX
#define CANBSIZ MAX_CANON
#define MAXPATHLEN PATH_MAX
#define NODEV ((dev_t) -1)
#define DEV_BSIZE 512
#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
#define howmany(x,y) (((x) + ((y) - 1)) / (y))
#define roundup(x,y) (__builtin_constant_p (y) && powerof2 (y) ? (((x) + (y) - 1) & ~((y) - 1)) : ((((x) + ((y) - 1)) / (y)) * (y)))
#define powerof2(x) ((((x) - 1) & (x)) == 0)
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define SAVE_ROOT_JMPBUF(th,stmt) do if (true) { stmt; } else if (th) { } while (0)
#define EC_PUSH_TAG(ec) do { rb_execution_context_t * const _ec = (ec); struct rb_vm_tag _tag; _tag.state = TAG_NONE; _tag.tag = Qundef; _tag.prev = _ec->tag; _tag.lock_rec = rb_ec_vm_lock_rec(_ec);
#define EC_POP_TAG() _ec->tag = _tag.prev; } while (0)
#define EC_TMPPOP_TAG() _ec->tag = _tag.prev
#define EC_REPUSH_TAG() (void)(_ec->tag = &_tag)
#define VAR_FROM_MEMORY(var) (var)
#define VAR_INITIALIZED(var) ((void)&(var))
#define VAR_NOCLOBBERED(var) var
#define EC_EXEC_TAG() (ruby_setjmp(_tag.buf) ? rb_ec_tag_state(VAR_FROM_MEMORY(_ec)) : (EC_REPUSH_TAG(), 0))
#define EC_JUMP_TAG(ec,st) rb_ec_tag_jump(ec, st)
#define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc)
#define CREF_FL_PUSHED_BY_EVAL IMEMO_FL_USER1
#define CREF_FL_OMOD_SHARED IMEMO_FL_USER2
#define CREF_FL_SINGLETON IMEMO_FL_USER3
#define rb_ec_raised_set(ec,f) ((ec)->raised_flag |= (f))
#define rb_ec_raised_reset(ec,f) ((ec)->raised_flag &= ~(f))
#define rb_ec_raised_p(ec,f) (((ec)->raised_flag & (f)) != 0)
#define rb_ec_raised_clear(ec) ((ec)->raised_flag = 0)
#define CharNext(p) rb_char_next(p)
#define RUBY_GC_H 1
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
#define RB_GC_SAVE_MACHINE_CONTEXT(th) do { FLUSH_REGISTER_WINDOWS; setjmp((th)->ec->machine.regs); SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); } while (0)
#define RUBY_MARK_FREE_DEBUG 0
#define RUBY_MARK_ENTER(msg)
#define RUBY_MARK_LEAVE(msg)
#define RUBY_FREE_ENTER(msg)
#define RUBY_FREE_LEAVE(msg)
#define RUBY_GC_INFO if(0)printf
#define RUBY_MARK_MOVABLE_UNLESS_NULL(ptr) do { VALUE markobj = (ptr); if (RTEST(markobj)) {rb_gc_mark_movable(markobj);} } while (0)
#define RUBY_MARK_UNLESS_NULL(ptr) do { VALUE markobj = (ptr); if (RTEST(markobj)) {rb_gc_mark(markobj);} } while (0)
#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}
#define STACK_UPPER(x,a,b) (b)
#define STACK_GROW_DIR_DETECTION
#define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
#define IS_STACK_DIR_UPPER() STACK_DIR_UPPER(1,0)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_COMPILE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_CONT_H
#define RUBY_ISEQ_H 1
#define ISEQ_MAJOR_VERSION ((unsigned int)ruby_api_version[0])
#define ISEQ_MINOR_VERSION ((unsigned int)ruby_api_version[1])
#define ISEQ_MBITS_SIZE sizeof(iseq_bits_t)
#define ISEQ_MBITS_BITLENGTH (ISEQ_MBITS_SIZE * CHAR_BIT)
#define ISEQ_MBITS_SET(buf,i) (buf[(i) / ISEQ_MBITS_BITLENGTH] |= ((iseq_bits_t)1 << ((i) % ISEQ_MBITS_BITLENGTH)))
#define ISEQ_MBITS_SET_P(buf,i) ((buf[(i) / ISEQ_MBITS_BITLENGTH] >> ((i) % ISEQ_MBITS_BITLENGTH)) & 0x1)
#define ISEQ_MBITS_BUFLEN(size) roomof(size, ISEQ_MBITS_BITLENGTH)
#define USE_ISEQ_NODE_ID 1
#define ISEQ_COVERAGE(iseq) ISEQ_BODY(iseq)->variable.coverage
#define ISEQ_COVERAGE_SET(iseq,cov) RB_OBJ_WRITE(iseq, &ISEQ_BODY(iseq)->variable.coverage, cov)
#define ISEQ_LINE_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_LINES)
#define ISEQ_BRANCH_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_BRANCHES)
#define ISEQ_PC2BRANCHINDEX(iseq) ISEQ_BODY(iseq)->variable.pc2branchindex
#define ISEQ_PC2BRANCHINDEX_SET(iseq,h) RB_OBJ_WRITE(iseq, &ISEQ_BODY(iseq)->variable.pc2branchindex, h)
#define ISEQ_FLIP_CNT(iseq) ISEQ_BODY(iseq)->variable.flip_count
#define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE | RUBY_EVENT_CLASS | RUBY_EVENT_END | RUBY_EVENT_CALL | RUBY_EVENT_RETURN| RUBY_EVENT_C_CALL| RUBY_EVENT_C_RETURN| RUBY_EVENT_B_CALL| RUBY_EVENT_B_RETURN| RUBY_EVENT_COVERAGE_LINE| RUBY_EVENT_COVERAGE_BRANCH)
#define ISEQ_NOT_LOADED_YET IMEMO_FL_USER1
#define ISEQ_USE_COMPILE_DATA IMEMO_FL_USER2
#define ISEQ_TRANSLATED IMEMO_FL_USER3
#define ISEQ_EXECUTABLE_P(iseq) (FL_TEST_RAW(((VALUE)iseq), ISEQ_NOT_LOADED_YET | ISEQ_USE_COMPILE_DATA) == 0)
#pragma GCC visibility push(default)
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512)
#pragma GCC visibility pop
#define INTERNAL_ERROR_H
#define INTERNAL_STRING_H
#define RUBY_ENCODING_H 1
#define RUBY_INTERNAL_ENCODING_CODERANGE_H
#pragma GCC visibility push(default)
#define ENC_CODERANGE_MASK RUBY_ENC_CODERANGE_MASK
#define ENC_CODERANGE_UNKNOWN RUBY_ENC_CODERANGE_UNKNOWN
#define ENC_CODERANGE_7BIT RUBY_ENC_CODERANGE_7BIT
#define ENC_CODERANGE_VALID RUBY_ENC_CODERANGE_VALID
#define ENC_CODERANGE_BROKEN RUBY_ENC_CODERANGE_BROKEN
#define ENC_CODERANGE_CLEAN_P(cr) RB_ENC_CODERANGE_CLEAN_P(cr)
#define ENC_CODERANGE(obj) RB_ENC_CODERANGE(obj)
#define ENC_CODERANGE_ASCIIONLY(obj) RB_ENC_CODERANGE_ASCIIONLY(obj)
#define ENC_CODERANGE_SET(obj,cr) RB_ENC_CODERANGE_SET(obj,cr)
#define ENC_CODERANGE_CLEAR(obj) RB_ENC_CODERANGE_CLEAR(obj)
#define ENC_CODERANGE_AND(a,b) RB_ENC_CODERANGE_AND(a, b)
#define ENCODING_CODERANGE_SET(obj,encindex,cr) RB_ENCODING_CODERANGE_SET(obj, encindex, cr)
#define RB_ENC_CODERANGE RB_ENC_CODERANGE
#define RB_ENC_CODERANGE_AND RB_ENC_CODERANGE_AND
#define RB_ENC_CODERANGE_ASCIIONLY RB_ENC_CODERANGE_ASCIIONLY
#define RB_ENC_CODERANGE_CLEAN_P RB_ENC_CODERANGE_CLEAN_P
#define RB_ENC_CODERANGE_CLEAR RB_ENC_CODERANGE_CLEAR
#define RB_ENC_CODERANGE_SET RB_ENC_CODERANGE_SET
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_CTYPE_H
#define ONIGMO_H
#define ONIGMO_VERSION_MAJOR 6
#define ONIGMO_VERSION_MINOR 1
#define ONIGMO_VERSION_TEENY 3
#define ONIG_EXTERN RUBY_EXTERN
#pragma GCC visibility push(default)
#define UChar OnigUChar
#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0)
#define OnigCodePointMaskWidth 3
#define OnigCodePointMask ((1<<OnigCodePointMaskWidth)-1)
#define OnigCodePointCount(n) ((n)&OnigCodePointMask)
#define OnigCaseFoldFlags(n) ((n)&~OnigCodePointMask)
#define OnigSpecialIndexShift 3
#define OnigSpecialIndexWidth 10
#define ONIGENC_CASE_UPCASE (1<<13)
#define ONIGENC_CASE_DOWNCASE (1<<14)
#define ONIGENC_CASE_TITLECASE (1<<15)
#define ONIGENC_CASE_SPECIAL_OFFSET 3
#define ONIGENC_CASE_UP_SPECIAL (1<<16)
#define ONIGENC_CASE_DOWN_SPECIAL (1<<17)
#define ONIGENC_CASE_MODIFIED (1<<18)
#define ONIGENC_CASE_FOLD (1<<19)
#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20)
#define ONIGENC_CASE_FOLD_LITHUANIAN (1<<21)
#define ONIGENC_CASE_ASCII_ONLY (1<<22)
#define ONIGENC_CASE_IS_TITLECASE (1<<23)
#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30)
#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag
#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3
#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13
#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0])
#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1]
#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2]
#define ONIG_ENCODING_ASCII (&OnigEncodingASCII)
#define ONIG_ENCODING_UNDEF ((OnigEncoding )0)
#define ONIGENC_CODE_TO_MBC_MAXLEN 7
#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18
#define ONIGENC_CTYPE_NEWLINE 0
#define ONIGENC_CTYPE_ALPHA 1
#define ONIGENC_CTYPE_BLANK 2
#define ONIGENC_CTYPE_CNTRL 3
#define ONIGENC_CTYPE_DIGIT 4
#define ONIGENC_CTYPE_GRAPH 5
#define ONIGENC_CTYPE_LOWER 6
#define ONIGENC_CTYPE_PRINT 7
#define ONIGENC_CTYPE_PUNCT 8
#define ONIGENC_CTYPE_SPACE 9
#define ONIGENC_CTYPE_UPPER 10
#define ONIGENC_CTYPE_XDIGIT 11
#define ONIGENC_CTYPE_WORD 12
#define ONIGENC_CTYPE_ALNUM 13
#define ONIGENC_CTYPE_ASCII 14
#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII
#define ONIGENC_FLAG_NONE 0U
#define ONIGENC_FLAG_UNICODE 1U
#define onig_enc_len(enc,p,e) ONIGENC_MBC_ENC_LEN(enc, p, e)
#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF)
#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1)
#define ONIGENC_IS_MBC_HEAD(enc,p,e) (ONIGENC_MBC_ENC_LEN(enc,p,e) != 1)
#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128)
#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128)
#define ONIGENC_IS_MBC_WORD(enc,s,end) ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
#define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) onigenc_ascii_is_code_ctype( ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc)
#define ONIGENC_IS_UNICODE(enc) ((enc)->flags & ONIGENC_FLAG_UNICODE)
#define ONIGENC_NAME(enc) ((enc)->name)
#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf,enc)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) (enc)->is_allowed_reverse_match(s,end,enc)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s,end) (enc)->left_adjust_char_head(start, s, end, enc)
#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) (enc)->apply_all_case_fold(case_fold_flag,f,arg,enc)
#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs,enc)
#define ONIGENC_STEP_BACK(enc,start,s,end,n) onigenc_step_back((enc),(start),(s),(end),(n))
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n) (n)
#define ONIGENC_MBCLEN_CHARFOUND_P(r) (0 < (r))
#define ONIGENC_MBCLEN_CHARFOUND_LEN(r) (r)
#define ONIGENC_CONSTRUCT_MBCLEN_INVALID() (-1)
#define ONIGENC_MBCLEN_INVALID_P(r) ((r) == -1)
#define ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n) (-1-(n))
#define ONIGENC_MBCLEN_NEEDMORE_P(r) ((r) < -1)
#define ONIGENC_MBCLEN_NEEDMORE_LEN(r) (-1-(r))
#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e) (enc)->precise_mbc_enc_len(p,e,enc)
#define ONIGENC_MBC_ENC_LEN(enc,p,e) onigenc_mbclen(p,e,enc)
#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len)
#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc)
#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len)
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end),enc)
#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end),enc)
#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code,enc)
#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf,enc)
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) (enc)->property_name_to_ctype(enc,p,end)
#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype,enc)
#define ONIGENC_IS_CODE_NEWLINE(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
#define ONIGENC_IS_CODE_GRAPH(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
#define ONIGENC_IS_CODE_PRINT(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
#define ONIGENC_IS_CODE_ALNUM(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
#define ONIGENC_IS_CODE_ALPHA(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
#define ONIGENC_IS_CODE_LOWER(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
#define ONIGENC_IS_CODE_UPPER(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
#define ONIGENC_IS_CODE_CNTRL(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
#define ONIGENC_IS_CODE_PUNCT(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
#define ONIGENC_IS_CODE_SPACE(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
#define ONIGENC_IS_CODE_BLANK(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
#define ONIGENC_IS_CODE_DIGIT(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
#define ONIGENC_IS_CODE_XDIGIT(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
#define ONIGENC_IS_CODE_WORD(enc,code) ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)
#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) (enc)->get_ctype_code_range(ctype,sbout,ranges,enc)
#define ONIG_NREGION 4
#define ONIG_MAX_CAPTURE_GROUP_NUM 32767
#define ONIG_MAX_BACKREF_NUM 1000
#define ONIG_MAX_REPEAT_NUM 100000
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000
#define ONIG_MAX_ERROR_MESSAGE_LEN 90
#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE
#define ONIG_OPTION_NONE 0U
#define ONIG_OPTION_IGNORECASE 1U
#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1)
#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1)
#define ONIG_OPTION_DOTALL ONIG_OPTION_MULTILINE
#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1)
#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1)
#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1)
#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1)
#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1)
#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1)
#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1)
#define ONIG_OPTION_NOTBOS (ONIG_OPTION_NOTEOL << 1)
#define ONIG_OPTION_NOTEOS (ONIG_OPTION_NOTBOS << 1)
#define ONIG_OPTION_ASCII_RANGE (ONIG_OPTION_NOTEOS << 1)
#define ONIG_OPTION_POSIX_BRACKET_ALL_RANGE (ONIG_OPTION_ASCII_RANGE << 1)
#define ONIG_OPTION_WORD_BOUND_ALL_RANGE (ONIG_OPTION_POSIX_BRACKET_ALL_RANGE << 1)
#define ONIG_OPTION_NEWLINE_CRLF (ONIG_OPTION_WORD_BOUND_ALL_RANGE << 1)
#define ONIG_OPTION_MAXBIT ONIG_OPTION_NEWLINE_CRLF
#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt))
#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt))
#define ONIG_IS_OPTION_ON(options,option) ((options) & (option))
#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS)
#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic)
#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended)
#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs)
#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep)
#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex)
#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava)
#define ONIG_SYNTAX_PERL58 (&OnigSyntaxPerl58)
#define ONIG_SYNTAX_PERL58_NG (&OnigSyntaxPerl58_NG)
#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl)
#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby)
#define ONIG_SYNTAX_PYTHON (&OnigSyntaxPython)
#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0)
#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1)
#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2)
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3)
#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4)
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5)
#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6)
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7)
#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8)
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9)
#define ONIG_SYN_OP_VBAR_ALT (1U<<10)
#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11)
#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12)
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13)
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14)
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15)
#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16)
#define ONIG_SYN_OP_BRACKET_CC (1U<<17)
#define ONIG_SYN_OP_ESC_W_WORD (1U<<18)
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19)
#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20)
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21)
#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22)
#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23)
#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24)
#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25)
#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26)
#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27)
#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28)
#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29)
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30)
#define ONIG_SYN_OP_ESC_O_BRACE_OCTAL (1U<<31)
#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0)
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1)
#define ONIG_SYN_OP2_OPTION_PERL (1U<<2)
#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3)
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4)
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5)
#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6)
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7)
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8)
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9)
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10)
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11)
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12)
#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13)
#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14)
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15)
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16)
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17)
#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19)
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20)
#define ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK (1U<<21)
#define ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER (1U<<22)
#define ONIG_SYN_OP2_ESC_V_VERTICAL_WHITESPACE (1U<<23)
#define ONIG_SYN_OP2_ESC_H_HORIZONTAL_WHITESPACE (1U<<24)
#define ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP (1U<<25)
#define ONIG_SYN_OP2_ESC_G_BRACE_BACKREF (1U<<26)
#define ONIG_SYN_OP2_QMARK_SUBEXP_CALL (1U<<27)
#define ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET (1U<<28)
#define ONIG_SYN_OP2_QMARK_LPAREN_CONDITION (1U<<29)
#define ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP (1U<<30)
#define ONIG_SYN_OP2_QMARK_TILDE_ABSENT (1U<<31)
#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31)
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0)
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1)
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2)
#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3)
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4)
#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5)
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6)
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7)
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8)
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9)
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL (1U<<10)
#define ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP (1U<<11)
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20)
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21)
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22)
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23)
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24)
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25)
#define ONIG_SYN_WARN_CC_DUP (1U<<26)
#define ONIG_META_CHAR_ESCAPE 0
#define ONIG_META_CHAR_ANYCHAR 1
#define ONIG_META_CHAR_ANYTIME 2
#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3
#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4
#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5
#define ONIG_INEFFECTIVE_META_CHAR 0
#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000)
#define ONIG_NORMAL 0
#define ONIG_MISMATCH -1
#define ONIG_NO_SUPPORT_CONFIG -2
#define ONIGERR_MEMORY -5
#define ONIGERR_TYPE_BUG -6
#define ONIGERR_PARSER_BUG -11
#define ONIGERR_STACK_BUG -12
#define ONIGERR_UNDEFINED_BYTECODE -13
#define ONIGERR_UNEXPECTED_BYTECODE -14
#define ONIGERR_MATCH_STACK_LIMIT_OVER -15
#define ONIGERR_PARSE_DEPTH_LIMIT_OVER -16
#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SET -21
#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22
#define ONIGERR_INVALID_ARGUMENT -30
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100
#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101
#define ONIGERR_EMPTY_CHAR_CLASS -102
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103
#define ONIGERR_END_PATTERN_AT_ESCAPE -104
#define ONIGERR_END_PATTERN_AT_META -105
#define ONIGERR_END_PATTERN_AT_CONTROL -106
#define ONIGERR_META_CODE_SYNTAX -108
#define ONIGERR_CONTROL_CODE_SYNTAX -109
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110
#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114
#define ONIGERR_NESTED_REPEAT_OPERATOR -115
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117
#define ONIGERR_END_PATTERN_IN_GROUP -118
#define ONIGERR_UNDEFINED_GROUP_OPTION -119
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121
#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123
#define ONIGERR_INVALID_CONDITION_PATTERN -124
#define ONIGERR_TOO_BIG_NUMBER -200
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206
#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207
#define ONIGERR_INVALID_BACKREF -208
#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209
#define ONIGERR_TOO_MANY_CAPTURE_GROUPS -210
#define ONIGERR_TOO_SHORT_DIGITS -211
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212
#define ONIGERR_EMPTY_GROUP_NAME -214
#define ONIGERR_INVALID_GROUP_NAME -215
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216
#define ONIGERR_UNDEFINED_NAME_REFERENCE -217
#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218
#define ONIGERR_MULTIPLEX_DEFINED_NAME -219
#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220
#define ONIGERR_NEVER_ENDING_RECURSION -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223
#define ONIGERR_INVALID_CODE_POINT_VALUE -400
#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402
#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403
#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r,i) ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])
#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1
#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2
#define ONIG_TRAVERSE_CALLBACK_AT_BOTH ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )
#define ONIG_REGION_NOTPOS -1
#define ONIG_NULL_WARN onig_null_warn
#define ONIG_CHAR_TABLE_SIZE 256
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_ENCODING_H
#define ONIGURUMA_H
#define ONIGURUMA
#define ONIGURUMA_VERSION_MAJOR ONIGMO_VERSION_MAJOR
#define ONIGURUMA_VERSION_MINOR ONIGMO_VERSION_MINOR
#define ONIGURUMA_VERSION_TEENY ONIGMO_VERSION_TEENY
#pragma GCC visibility push(default)
#define ENCODING_INLINE_MAX RUBY_ENCODING_INLINE_MAX
#define ENCODING_SHIFT RUBY_ENCODING_SHIFT
#define ENCODING_MASK RUBY_ENCODING_MASK
#define ENCODING_SET_INLINED(obj,i) RB_ENCODING_SET_INLINED(obj,i)
#define ENCODING_SET(obj,i) RB_ENCODING_SET(obj,i)
#define ENCODING_GET_INLINED(obj) RB_ENCODING_GET_INLINED(obj)
#define ENCODING_GET(obj) RB_ENCODING_GET(obj)
#define ENCODING_IS_ASCII8BIT(obj) RB_ENCODING_IS_ASCII8BIT(obj)
#define ENCODING_MAXNAMELEN RUBY_ENCODING_MAXNAMELEN
#define MBCLEN_CHARFOUND_P(ret) ONIGENC_MBCLEN_CHARFOUND_P(ret)
#define MBCLEN_CHARFOUND_LEN(ret) ONIGENC_MBCLEN_CHARFOUND_LEN(ret)
#define MBCLEN_INVALID_P(ret) ONIGENC_MBCLEN_INVALID_P(ret)
#define MBCLEN_NEEDMORE_P(ret) ONIGENC_MBCLEN_NEEDMORE_P(ret)
#define MBCLEN_NEEDMORE_LEN(ret) ONIGENC_MBCLEN_NEEDMORE_LEN(ret)
#pragma GCC visibility pop
#define RB_ENCODING_GET RB_ENCODING_GET
#define RB_ENCODING_GET_INLINED RB_ENCODING_GET_INLINED
#define RB_ENCODING_IS_ASCII8BIT RB_ENCODING_IS_ASCII8BIT
#define RB_ENCODING_SET RB_ENCODING_SET
#define RB_ENCODING_SET_INLINED RB_ENCODING_SET_INLINED
#define rb_enc_asciicompat rb_enc_asciicompat
#define rb_enc_code_to_mbclen rb_enc_code_to_mbclen
#define rb_enc_codepoint rb_enc_codepoint
#define rb_enc_left_char_head rb_enc_left_char_head
#define rb_enc_mbc_to_codepoint rb_enc_mbc_to_codepoint
#define rb_enc_mbcput rb_enc_mbcput
#define rb_enc_mbmaxlen rb_enc_mbmaxlen
#define rb_enc_mbminlen rb_enc_mbminlen
#define rb_enc_name rb_enc_name
#define rb_enc_prev_char rb_enc_prev_char
#define rb_enc_right_char_head rb_enc_right_char_head
#define rb_enc_step_back rb_enc_step_back
#define rb_enc_str_asciicompat_p rb_enc_str_asciicompat_p
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_enc_is_newline rb_enc_is_newline
#define rb_enc_isalnum rb_enc_isalnum
#define rb_enc_isalpha rb_enc_isalpha
#define rb_enc_isascii rb_enc_isascii
#define rb_enc_isctype rb_enc_isctype
#define rb_enc_isdigit rb_enc_isdigit
#define rb_enc_islower rb_enc_islower
#define rb_enc_isprint rb_enc_isprint
#define rb_enc_iscntrl rb_enc_iscntrl
#define rb_enc_ispunct rb_enc_ispunct
#define rb_enc_isspace rb_enc_isspace
#define rb_enc_isupper rb_enc_isupper
#define RUBY_INTERNAL_ENCODING_PATHNAME_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_RE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_SPRINTF_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_STRING_H
#pragma GCC visibility push(default)
#define rb_enc_str_new(str,len,enc) ((RBIMPL_CONSTANT_P(str) && RBIMPL_CONSTANT_P(len) ? rb_enc_str_new_static: rb_enc_str_new) ((str), (len), (enc)))
#define rb_enc_str_new_cstr(str,enc) ((RBIMPL_CONSTANT_P(str) ? rbimpl_enc_str_new_cstr : rb_enc_str_new_cstr) ((str), (enc)))
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_SYMBOL_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_INTERNAL_ENCODING_TRANSCODE_H
#pragma GCC visibility push(default)
#define ECONV_ERROR_HANDLER_MASK RUBY_ECONV_ERROR_HANDLER_MASK
#define ECONV_INVALID_MASK RUBY_ECONV_INVALID_MASK
#define ECONV_INVALID_REPLACE RUBY_ECONV_INVALID_REPLACE
#define ECONV_UNDEF_MASK RUBY_ECONV_UNDEF_MASK
#define ECONV_UNDEF_REPLACE RUBY_ECONV_UNDEF_REPLACE
#define ECONV_UNDEF_HEX_CHARREF RUBY_ECONV_UNDEF_HEX_CHARREF
#define ECONV_DECORATOR_MASK RUBY_ECONV_DECORATOR_MASK
#define ECONV_NEWLINE_DECORATOR_MASK RUBY_ECONV_NEWLINE_DECORATOR_MASK
#define ECONV_NEWLINE_DECORATOR_READ_MASK RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR
#define ECONV_CRLF_NEWLINE_DECORATOR RUBY_ECONV_CRLF_NEWLINE_DECORATOR
#define ECONV_CR_NEWLINE_DECORATOR RUBY_ECONV_CR_NEWLINE_DECORATOR
#define ECONV_LF_NEWLINE_DECORATOR RUBY_ECONV_LF_NEWLINE_DECORATOR
#define ECONV_XML_TEXT_DECORATOR RUBY_ECONV_XML_TEXT_DECORATOR
#define ECONV_XML_ATTR_CONTENT_DECORATOR RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR
#define ECONV_STATEFUL_DECORATOR_MASK RUBY_ECONV_STATEFUL_DECORATOR_MASK
#define ECONV_XML_ATTR_QUOTE_DECORATOR RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR
#define ECONV_DEFAULT_NEWLINE_DECORATOR RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR
#define ECONV_PARTIAL_INPUT RUBY_ECONV_PARTIAL_INPUT
#define ECONV_AFTER_OUTPUT RUBY_ECONV_AFTER_OUTPUT
#pragma GCC visibility pop
#define STR_NOEMBED FL_USER1
#define STR_SHARED FL_USER2
#undef rb_fstring_cstr
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
#define rb_fstring_literal(str) rb_fstring_lit(str)
#define rb_fstring_enc_lit(str,enc) rb_fstring_enc_new((str), rb_strlen_lit(str), (enc))
#define rb_fstring_enc_literal(str,enc) rb_fstring_enc_lit(str, enc)
#define rb_fstring_cstr(str) (__builtin_constant_p(str) ? rb_fstring_new((str), (long)strlen(str)) : (rb_fstring_cstr)(str))
#undef Check_Type
#define rb_raise_static(e,m) rb_raise_cstr_i((e), rb_str_new_static((m), rb_strlen_lit(m)))
#define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
#define rb_syserr_fail_path(err,path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
#define rb_syserr_new_path(err,path) rb_syserr_new_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
#define rb_warn_deprecated_to_remove_at(removal,...) rb_warn_deprecated_to_remove(#removal, __VA_ARGS__)
#define RUBY_VERSION_SINCE(major,minor) 0
#define RUBY_VERSION_BEFORE(major,minor) 0
#define RBIMPL_TODO0(x)
#define RBIMPL_TODO(message) RBIMPL_TODO0("TODO: " message)
#define rb_typeddata_is_instance_of rb_typeddata_is_instance_of_inline
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_EVAL_H
#define id_signo ruby_static_id_signo
#define id_status ruby_static_id_status
#define INTERNAL_INITS_H
#define INTERNAL_OBJECT_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_PARSE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_PROC_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_RE_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_SYMBOL_H
#undef rb_sym_intern_ascii_cstr
#define rb_sym_intern_ascii_cstr(ptr) (__builtin_constant_p(ptr) ? rb_sym_intern_ascii((ptr), (long)strlen(ptr)) : rb_sym_intern_ascii_cstr(ptr))
#define INTERNAL_THREAD_H
#define COVERAGE_INDEX_LINES 0
#define COVERAGE_INDEX_BRANCHES 1
#define COVERAGE_TARGET_LINES 1
#define COVERAGE_TARGET_BRANCHES 2
#define COVERAGE_TARGET_METHODS 4
#define COVERAGE_TARGET_ONESHOT_LINES 8
#define COVERAGE_TARGET_EVAL 16
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_SANITIZERS_H
#define SANITIZER_ASAN_INTERFACE_H
#define SANITIZER_COMMON_INTERFACE_DEFS_H
#define ASAN_POISON_MEMORY_REGION(addr,size) ((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr,size) ((void)(addr), (void)(size))
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) NO_SANITIZE_ADDRESS(NOINLINE(x))
#define INTERNAL_WARNINGS_H
#define COMPILER_WARNING_PUSH RBIMPL_WARNING_PUSH()
#define COMPILER_WARNING_POP RBIMPL_WARNING_POP()
#define COMPILER_WARNING_ERROR(flag) RBIMPL_WARNING_ERROR(flag)
#define COMPILER_WARNING_IGNORED(flag) RBIMPL_WARNING_IGNORED(flag)
#undef NO_SANITIZE
#define NO_SANITIZE(x,y) COMPILER_WARNING_PUSH; COMPILER_WARNING_IGNORED(-Wattributes); __attribute__((__no_sanitize__(x))) y; COMPILER_WARNING_POP
#define __asan_poison_memory_region(x,y)
#define __asan_unpoison_memory_region(x,y)
#define __asan_region_is_poisoned(x,y) 0
#define __msan_allocated_memory(x,y) ((void)(x), (void)(y))
#define __msan_poison(x,y) ((void)(x), (void)(y))
#define __msan_unpoison(x,y) ((void)(x), (void)(y))
#define __msan_unpoison_string(x) ((void)(x))
#define VALGRIND_MAKE_MEM_DEFINED(p,n) 0
#define VALGRIND_MAKE_MEM_UNDEFINED(p,n) 0
#define INTERNAL_VARIABLE_H
#define CONSTANT_H
#define RUBY_ID_TABLE_H 1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RB_CONST_PRIVATE_P(ce) (((ce)->flag & CONST_VISIBILITY_MASK) == CONST_PRIVATE)
#define RB_CONST_PUBLIC_P(ce) (((ce)->flag & CONST_VISIBILITY_MASK) == CONST_PUBLIC)
#define RB_CONST_DEPRECATED_P(ce) ((ce)->flag & CONST_DEPRECATED)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define ROBJECT_TRANSIENT_FLAG FL_USER2
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_MJIT_H 1
#define RUBY_H 1
#define HAVE_RUBY_ATOMIC_H 1
#define HAVE_RUBY_DEBUG_H 1
#define HAVE_RUBY_DEFINES_H 1
#define HAVE_RUBY_ENCODING_H 1
#define HAVE_RUBY_FIBER_SCHEDULER_H 1
#define HAVE_RUBY_INTERN_H 1
#define HAVE_RUBY_IO_H 1
#define HAVE_RUBY_MEMORY_VIEW_H 1
#define HAVE_RUBY_MISSING_H 1
#define HAVE_RUBY_ONIGMO_H 1
#define HAVE_RUBY_ONIGURUMA_H 1
#define HAVE_RUBY_RACTOR_H 1
#define HAVE_RUBY_RANDOM_H 1
#define HAVE_RUBY_RE_H 1
#define HAVE_RUBY_REGEX_H 1
#define HAVE_RUBY_RUBY_H 1
#define HAVE_RUBY_ST_H 1
#define HAVE_RUBY_THREAD_H 1
#define HAVE_RUBY_THREAD_NATIVE_H 1
#define HAVE_RUBY_UTIL_H 1
#define HAVE_RUBY_VERSION_H 1
#define HAVE_RUBY_VM_H 1
#define MJIT_FUNC_STATE_P(jit_func) ((uintptr_t)(jit_func) <= (uintptr_t)MJIT_FUNC_FAILED)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define mjit_enabled true
#define YJIT_H 1
#define YJIT_STATS RUBY_DEBUG
#define RUBY_VM_H 1
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_VM_CALLINFO_H
#define USE_DEBUG_COUNTER 0
#define RUBY_DEBUG_COUNTER_H 1
#define RB_DEBUG_COUNTER(name) RB_DEBUG_COUNTER_ ##name,
#undef RB_DEBUG_COUNTER
#define RB_DEBUG_COUNTER_INC(type) ((void)0)
#define RB_DEBUG_COUNTER_INC_UNLESS(type,cond) (!!(cond))
#define RB_DEBUG_COUNTER_INC_IF(type,cond) (!!(cond))
#define RB_DEBUG_COUNTER_ADD(type,num) ((void)0)
#define RB_DEBUG_COUNTER_SETMAX(type,num) 0
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_CLASS_H
#define RCLASS_EXT(c) ((rb_classext_t *)((char *)(c) + sizeof(struct RClass)))
#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
#define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
#define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
#define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
#define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator)
#define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
#define RICLASS_IS_ORIGIN FL_USER0
#define RCLASS_CLONED FL_USER1
#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define VM_CALL_ARGS_SPLAT (0x01 << VM_CALL_ARGS_SPLAT_bit)
#define VM_CALL_ARGS_BLOCKARG (0x01 << VM_CALL_ARGS_BLOCKARG_bit)
#define VM_CALL_FCALL (0x01 << VM_CALL_FCALL_bit)
#define VM_CALL_VCALL (0x01 << VM_CALL_VCALL_bit)
#define VM_CALL_ARGS_SIMPLE (0x01 << VM_CALL_ARGS_SIMPLE_bit)
#define VM_CALL_BLOCKISEQ (0x01 << VM_CALL_BLOCKISEQ_bit)
#define VM_CALL_KWARG (0x01 << VM_CALL_KWARG_bit)
#define VM_CALL_KW_SPLAT (0x01 << VM_CALL_KW_SPLAT_bit)
#define VM_CALL_TAILCALL (0x01 << VM_CALL_TAILCALL_bit)
#define VM_CALL_SUPER (0x01 << VM_CALL_SUPER_bit)
#define VM_CALL_ZSUPER (0x01 << VM_CALL_ZSUPER_bit)
#define VM_CALL_OPT_SEND (0x01 << VM_CALL_OPT_SEND_bit)
#define VM_CALL_KW_SPLAT_MUT (0x01 << VM_CALL_KW_SPLAT_MUT_bit)
#define USE_EMBED_CI 1
#define CI_EMBED_TAG_bits 1
#define CI_EMBED_ARGC_bits 15
#define CI_EMBED_FLAG_bits 16
#define CI_EMBED_ID_bits 32
#define CI_EMBED_FLAG 0x01
#define CI_EMBED_ARGC_SHFT (CI_EMBED_TAG_bits)
#define CI_EMBED_ARGC_MASK ((((VALUE)1)<<CI_EMBED_ARGC_bits) - 1)
#define CI_EMBED_FLAG_SHFT (CI_EMBED_TAG_bits + CI_EMBED_ARGC_bits)
#define CI_EMBED_FLAG_MASK ((((VALUE)1)<<CI_EMBED_FLAG_bits) - 1)
#define CI_EMBED_ID_SHFT (CI_EMBED_TAG_bits + CI_EMBED_ARGC_bits + CI_EMBED_FLAG_bits)
#define CI_EMBED_ID_MASK ((((VALUE)1)<<CI_EMBED_ID_bits) - 1)
#define vm_ci_new(mid,flag,argc,kwarg) vm_ci_new_(mid, flag, argc, kwarg, __FILE__, __LINE__)
#define vm_ci_new_runtime(mid,flag,argc,kwarg) vm_ci_new_runtime_(mid, flag, argc, kwarg, __FILE__, __LINE__)
#define VM_CI_EMBEDDABLE_P(mid,flag,argc,kwarg) (((mid ) & ~CI_EMBED_ID_MASK) ? false : ((flag) & ~CI_EMBED_FLAG_MASK) ? false : ((argc) & ~CI_EMBED_ARGC_MASK) ? false : (kwarg) ? false : true)
#define vm_ci_new_id(mid,flag,argc,must_zero) ((const struct rb_callinfo *) ((((VALUE)(mid )) << CI_EMBED_ID_SHFT) | (((VALUE)(flag)) << CI_EMBED_FLAG_SHFT) | (((VALUE)(argc)) << CI_EMBED_ARGC_SHFT) | RUBY_FIXNUM_FLAG))
#define VM_CALLINFO_NOT_UNDER_GC IMEMO_FL_USER0
#define VM_CI_ON_STACK(mid_,flags_,argc_,kwarg_) (struct rb_callinfo) { .flags = T_IMEMO | (imemo_callinfo << FL_USHIFT) | VM_CALLINFO_NOT_UNDER_GC, .mid = mid_, .flag = flags_, .argc = argc_, .kwarg = kwarg_, }
#define VM_CALLCACHE_UNMARKABLE FL_FREEZE
#define VM_CALLCACHE_ON_STACK FL_EXIVAR
#define vm_cc_empty() rb_vm_empty_cc()
#define VM_CC_ON_STACK(clazz,call,aux,cme) (struct rb_callcache) { .flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE | VM_CALLCACHE_ON_STACK, .klass = clazz, .cme_ = cme, .call_ = call, .aux_ = aux, }
#define RUBY_DEBUG_H
#pragma GCC visibility push(default)
#define dpv(h,v) ruby_debug_print_value(-1, 0, (h), (v))
#define dp(v) ruby_debug_print_value(-1, 0, "", (v))
#define dpi(i) ruby_debug_print_id(-1, 0, "", (i))
#define dpn(n) ruby_debug_print_node(-1, 0, "", (n))
#pragma GCC visibility pop
#define USE_RUBY_DEBUG_LOG 0
#define ruby_debug_log(...) RB_GNUC_EXTENSION_BLOCK( RBIMPL_WARNING_PUSH(); RBIMPL_WARNING_IGNORED(-Wformat-zero-length); ruby_debug_log(__VA_ARGS__); RBIMPL_WARNING_POP())
#define _RUBY_DEBUG_LOG(...) ruby_debug_log(__FILE__, __LINE__, RUBY_FUNCTION_NAME_STRING, "" __VA_ARGS__)
#define RUBY_DEBUG_LOG(...)
#define RUBY_DEBUG_LOG2(file,line,...)
#define RUBY_VM_EXEC_H
#define debugs
#define DEBUG_ENTER_INSN(insn)
#define DEBUG_END_INSN()
#define throwdebug if(0)ruby_debug_printf
#define USE_INSNS_COUNTER 0
#define LABEL(x) INSN_LABEL_ ##x
#define ELABEL(x) INSN_ELABEL_ ##x
#define LABEL_PTR(x) RB_GNUC_EXTENSION(&&LABEL(x))
#define INSN_ENTRY_SIG(insn) if (0) { ruby_debug_printf("exec: %s@(%"PRIdPTRDIFF", %"PRIdPTRDIFF")@%s:%u\n", #insn, (reg_pc - ISEQ_BODY(reg_cfp->iseq)->iseq_encoded), (reg_cfp->pc - ISEQ_BODY(reg_cfp->iseq)->iseq_encoded), RSTRING_PTR(rb_iseq_path(reg_cfp->iseq)), rb_iseq_line_no(reg_cfp->iseq, reg_pc - ISEQ_BODY(reg_cfp->iseq)->iseq_encoded)); } if (USE_INSNS_COUNTER) vm_insns_counter_count_insn(BIN(insn));
#define INSN_DISPATCH_SIG(insn)
#define INSN_ENTRY(insn) LABEL(insn): INSN_ENTRY_SIG(insn);
#define TC_DISPATCH(insn) INSN_DISPATCH_SIG(insn); RB_GNUC_EXTENSION_BLOCK(goto *(void const *)GET_CURRENT_INSN()); ;
#define END_INSN(insn) DEBUG_END_INSN(); TC_DISPATCH(insn);
#define INSN_DISPATCH() TC_DISPATCH(__START__) {
#define END_INSNS_DISPATCH() rb_bug("unknown insn: %"PRIdVALUE, GET_CURRENT_INSN()); }
#define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
#define START_OF_ORIGINAL_INSN(x) if (0) goto start_of_ ##x; start_of_ ##x:
#define DISPATCH_ORIGINAL_INSN(x) goto start_of_ ##x;
#define VM_SP_CNT(ec,sp) ((sp) - (ec)->vm_stack)
#define THROW_EXCEPTION(exc) do { ec->errinfo = (VALUE)(exc); EC_JUMP_TAG(ec, ec->tag->state); } while (0)
#define SCREG(r) (reg_ ##r)
#define VM_DEBUG_STACKOVERFLOW 0
#define CHECK_VM_STACK_OVERFLOW_FOR_INSN(cfp,margin)
#define INSN_LABEL2(insn,name) INSN_LABEL_ ## insn ## _ ## name
#define INSN_LABEL(x) INSN_LABEL2(NAME_OF_CURRENT_INSN, x)
#define RUBY_INSNHELPER_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define COLLECT_USAGE_INSN(insn)
#define COLLECT_USAGE_OPERAND(insn,n,op)
#define COLLECT_USAGE_REGISTER(reg,s)
#define PUSH(x) (SET_SV(x), INC_SP(1))
#define TOPN(n) (*(GET_SP()-(n)-1))
#define POPN(n) (DEC_SP(n))
#define POP() (DEC_SP(1))
#define STACK_ADDR_FROM_TOP(n) (GET_SP()-(n))
#define VM_REG_CFP (reg_cfp)
#define VM_REG_PC (VM_REG_CFP->pc)
#define VM_REG_SP (VM_REG_CFP->sp)
#define VM_REG_EP (VM_REG_CFP->ep)
#define RESTORE_REGS() do { VM_REG_CFP = ec->cfp; } while (0)
#define COLLECT_USAGE_REGISTER_HELPER(a,b,v) (v)
#define GET_PC() (COLLECT_USAGE_REGISTER_HELPER(PC, GET, VM_REG_PC))
#define SET_PC(x) (VM_REG_PC = (COLLECT_USAGE_REGISTER_HELPER(PC, SET, (x))))
#define GET_CURRENT_INSN() (*GET_PC())
#define GET_OPERAND(n) (GET_PC()[(n)])
#define ADD_PC(n) (SET_PC(VM_REG_PC + (n)))
#define JUMP(dst) (SET_PC(VM_REG_PC + (dst)))
#define GET_CFP() (COLLECT_USAGE_REGISTER_HELPER(CFP, GET, VM_REG_CFP))
#define GET_EP() (COLLECT_USAGE_REGISTER_HELPER(EP, GET, VM_REG_EP))
#define SET_EP(x) (VM_REG_EP = (COLLECT_USAGE_REGISTER_HELPER(EP, SET, (x))))
#define GET_LEP() (VM_EP_LEP(GET_EP()))
#define GET_SP() (COLLECT_USAGE_REGISTER_HELPER(SP, GET, VM_REG_SP))
#define SET_SP(x) (VM_REG_SP = (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x))))
#define INC_SP(x) (VM_REG_SP += (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x))))
#define DEC_SP(x) (VM_REG_SP -= (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x))))
#define SET_SV(x) (*GET_SP() = rb_ractor_confirm_belonging(x))
#define GET_ISEQ() (GET_CFP()->iseq)
#define GET_PREV_EP(ep) ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
#define GET_SELF() (COLLECT_USAGE_REGISTER_HELPER(SELF, GET, GET_CFP()->self))
#define GET_BLOCK_HANDLER() (GET_LEP()[VM_ENV_DATA_INDEX_SPECVAL])
#define SETUP_CANARY(cond) if (cond) {} else {}
#define CHECK_CANARY(cond,insn) if (cond) {(void)(insn);}
#define GET_GLOBAL_CVAR_STATE() (ruby_vm_global_cvar_state)
#define INC_GLOBAL_CVAR_STATE() (++ruby_vm_global_cvar_state)
#define IS_ARGS_SPLAT(ci) (vm_ci_flag(ci) & VM_CALL_ARGS_SPLAT)
#define IS_ARGS_KEYWORD(ci) (vm_ci_flag(ci) & VM_CALL_KWARG)
#define IS_ARGS_KW_SPLAT(ci) (vm_ci_flag(ci) & VM_CALL_KW_SPLAT)
#define IS_ARGS_KW_OR_KW_SPLAT(ci) (vm_ci_flag(ci) & (VM_CALL_KWARG | VM_CALL_KW_SPLAT))
#define IS_ARGS_KW_SPLAT_MUT(ci) (vm_ci_flag(ci) & VM_CALL_KW_SPLAT_MUT)
#define RUBY_RACTOR_H 1
#pragma GCC visibility push(default)
#define RB_RACTOR_LOCAL_STORAGE_TYPE_FREE (&rb_ractor_local_storage_type_free)
#pragma GCC visibility pop
#define RB_OBJ_SHAREABLE_P(obj) FL_TEST_RAW((obj), RUBY_FL_SHAREABLE)
#define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define rb_ractor_set_current_ec(cr,ec) rb_ractor_set_current_ec_(cr, ec, __FILE__, __LINE__)
#define rb_ractor_confirm_belonging(obj) obj
#define RUBY_VM_SYNC_H
#define LOCATION_ARGS void
#define LOCATION_PARAMS
#define APPEND_LOCATION_ARGS
#define APPEND_LOCATION_PARAMS
#define RB_VM_LOCKED_P() rb_vm_locked_p()
#define RB_VM_LOCK() rb_vm_lock(__FILE__, __LINE__)
#define RB_VM_UNLOCK() rb_vm_unlock(__FILE__, __LINE__)
#define RB_VM_LOCK_ENTER_CR_LEV(cr,levp) rb_vm_lock_enter_cr(cr, levp, __FILE__, __LINE__)
#define RB_VM_LOCK_LEAVE_CR_LEV(cr,levp) rb_vm_lock_leave_cr(cr, levp, __FILE__, __LINE__)
#define RB_VM_LOCK_ENTER_LEV(levp) rb_vm_lock_enter(levp, __FILE__, __LINE__)
#define RB_VM_LOCK_LEAVE_LEV(levp) rb_vm_lock_leave(levp, __FILE__, __LINE__)
#define RB_VM_LOCK_ENTER() { unsigned int _lev; RB_VM_LOCK_ENTER_LEV(&_lev);
#define RB_VM_LOCK_LEAVE() RB_VM_LOCK_LEAVE_LEV(&_lev); }
#define RB_VM_LOCK_ENTER_LEV_NB(levp) rb_vm_lock_enter_nb(levp, __FILE__, __LINE__)
#define RB_VM_LOCK_ENTER_NO_BARRIER() { unsigned int _lev; RB_VM_LOCK_ENTER_LEV_NB(&_lev);
#define RB_VM_LOCK_LEAVE_NO_BARRIER() RB_VM_LOCK_LEAVE_LEV(&_lev); }
#define ASSERT_vm_locking()
#define ASSERT_vm_unlocking()
#define BUILTIN_H_INCLUDED
#define RB_BUILTIN_FUNCTION(_i,_name,_fname,_arity,_compiler) { .name = _i < 0 ? NULL : #_name, .func_ptr = (void *)_fname, .argc = _arity, .index = _i, .compiler = _compiler, }
#define _PROBES_H
#define DTRACE_PROBES_DISABLED 1
#define RUBY_DTRACE_METHOD_ENTRY_ENABLED() 0
#define RUBY_DTRACE_METHOD_ENTRY(classname,methodname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_METHOD_RETURN_ENABLED() 0
#define RUBY_DTRACE_METHOD_RETURN(classname,methodname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_CMETHOD_ENTRY_ENABLED() 0
#define RUBY_DTRACE_CMETHOD_ENTRY(classname,methodname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_CMETHOD_RETURN_ENABLED() 0
#define RUBY_DTRACE_CMETHOD_RETURN(classname,methodname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_REQUIRE_ENTRY_ENABLED() 0
#define RUBY_DTRACE_REQUIRE_ENTRY(rquiredfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_REQUIRE_RETURN_ENABLED() 0
#define RUBY_DTRACE_REQUIRE_RETURN(requiredfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY_ENABLED() 0
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY(requiredfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED() 0
#define RUBY_DTRACE_FIND_REQUIRE_RETURN(requiredfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_LOAD_ENTRY_ENABLED() 0
#define RUBY_DTRACE_LOAD_ENTRY(loadedfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_LOAD_RETURN_ENABLED() 0
#define RUBY_DTRACE_LOAD_RETURN(loadedfile,filename,lineno) do {} while (0)
#define RUBY_DTRACE_RAISE_ENABLED() 0
#define RUBY_DTRACE_RAISE(classname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_OBJECT_CREATE_ENABLED() 0
#define RUBY_DTRACE_OBJECT_CREATE(classname,filename,lineno) do {} while (0)
#define RUBY_DTRACE_ARRAY_CREATE_ENABLED() 0
#define RUBY_DTRACE_ARRAY_CREATE(length,filename,lineno) do {} while (0)
#define RUBY_DTRACE_HASH_CREATE_ENABLED() 0
#define RUBY_DTRACE_HASH_CREATE(length,filename,lineno) do {} while (0)
#define RUBY_DTRACE_STRING_CREATE_ENABLED() 0
#define RUBY_DTRACE_STRING_CREATE(length,filename,lineno) do {} while (0)
#define RUBY_DTRACE_SYMBOL_CREATE_ENABLED() 0
#define RUBY_DTRACE_SYMBOL_CREATE(str,filename,lineno) do {} while (0)
#define RUBY_DTRACE_PARSE_BEGIN_ENABLED() 0
#define RUBY_DTRACE_PARSE_BEGIN(sourcefile,lineno) do {} while (0)
#define RUBY_DTRACE_PARSE_END_ENABLED() 0
#define RUBY_DTRACE_PARSE_END(sourcefile,lineno) do {} while (0)
#define RUBY_DTRACE_INSN_ENABLED() 0
#define RUBY_DTRACE_INSN(insns_name) do {} while (0)
#define RUBY_DTRACE_INSN_OPERAND_ENABLED() 0
#define RUBY_DTRACE_INSN_OPERAND(val,insns_name) do {} while (0)
#define RUBY_DTRACE_GC_MARK_BEGIN_ENABLED() 0
#define RUBY_DTRACE_GC_MARK_BEGIN() do {} while (0)
#define RUBY_DTRACE_GC_MARK_END_ENABLED() 0
#define RUBY_DTRACE_GC_MARK_END() do {} while (0)
#define RUBY_DTRACE_GC_SWEEP_BEGIN_ENABLED() 0
#define RUBY_DTRACE_GC_SWEEP_BEGIN() do {} while (0)
#define RUBY_DTRACE_GC_SWEEP_END_ENABLED() 0
#define RUBY_DTRACE_GC_SWEEP_END() do {} while (0)
#define RUBY_PROBES_HELPER_H
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define RUBY_DTRACE_METHOD_HOOK(name,ec,klazz,id) do { if (UNLIKELY(RUBY_DTRACE_ ##name ##_ENABLED())) { struct ruby_dtrace_method_hook_args args; if (rb_dtrace_setup(ec, klazz, id, &args)) { RUBY_DTRACE_ ##name(args.classname, args.methodname, args.filename, args.line_no); } } } while (0)
#define RUBY_DTRACE_METHOD_ENTRY_HOOK(ec,klass,id) RUBY_DTRACE_METHOD_HOOK(METHOD_ENTRY, ec, klass, id)
#define RUBY_DTRACE_METHOD_RETURN_HOOK(ec,klass,id) RUBY_DTRACE_METHOD_HOOK(METHOD_RETURN, ec, klass, id)
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec,klass,id) RUBY_DTRACE_METHOD_HOOK(CMETHOD_ENTRY, ec, klass, id)
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(ec,klass,id) RUBY_DTRACE_METHOD_HOOK(CMETHOD_RETURN, ec, klass, id)
#define _STDATOMIC_H
#define ATOMIC_VAR_INIT(VALUE) (VALUE)
#define atomic_init(PTR,VAL) atomic_store_explicit (PTR, VAL, __ATOMIC_RELAXED)
#define kill_dependency(Y) __extension__ ({ __auto_type __kill_dependency_tmp = (Y); __kill_dependency_tmp; })
#define atomic_thread_fence(MO) __atomic_thread_fence (MO)
#define atomic_signal_fence(MO) __atomic_signal_fence (MO)
#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#define atomic_store_explicit(PTR,VAL,MO) __extension__ ({ __auto_type __atomic_store_ptr = (PTR); __typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL); __atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO)); })
#define atomic_store(PTR,VAL) atomic_store_explicit (PTR, VAL, __ATOMIC_SEQ_CST)
#define atomic_load_explicit(PTR,MO) __extension__ ({ __auto_type __atomic_load_ptr = (PTR); __typeof__ (*__atomic_load_ptr) __atomic_load_tmp; __atomic_load (__atomic_load_ptr, &__atomic_load_tmp, (MO)); __atomic_load_tmp; })
#define atomic_load(PTR) atomic_load_explicit (PTR, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit(PTR,VAL,MO) __extension__ ({ __auto_type __atomic_exchange_ptr = (PTR); __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_val = (VAL); __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_tmp; __atomic_exchange (__atomic_exchange_ptr, &__atomic_exchange_val, &__atomic_exchange_tmp, (MO)); __atomic_exchange_tmp; })
#define atomic_exchange(PTR,VAL) atomic_exchange_explicit (PTR, VAL, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong_explicit(PTR,VAL,DES,SUC,FAIL) __extension__ ({ __auto_type __atomic_compare_exchange_ptr = (PTR); __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp = (DES); __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), &__atomic_compare_exchange_tmp, 0, (SUC), (FAIL)); })
#define atomic_compare_exchange_strong(PTR,VAL,DES) atomic_compare_exchange_strong_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit(PTR,VAL,DES,SUC,FAIL) __extension__ ({ __auto_type __atomic_compare_exchange_ptr = (PTR); __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp = (DES); __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), &__atomic_compare_exchange_tmp, 1, (SUC), (FAIL)); })
#define atomic_compare_exchange_weak(PTR,VAL,DES) atomic_compare_exchange_weak_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_fetch_add(PTR,VAL) __atomic_fetch_add ((PTR), (VAL), __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit(PTR,VAL,MO) __atomic_fetch_add ((PTR), (VAL), (MO))
#define atomic_fetch_sub(PTR,VAL) __atomic_fetch_sub ((PTR), (VAL), __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit(PTR,VAL,MO) __atomic_fetch_sub ((PTR), (VAL), (MO))
#define atomic_fetch_or(PTR,VAL) __atomic_fetch_or ((PTR), (VAL), __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit(PTR,VAL,MO) __atomic_fetch_or ((PTR), (VAL), (MO))
#define atomic_fetch_xor(PTR,VAL) __atomic_fetch_xor ((PTR), (VAL), __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit(PTR,VAL,MO) __atomic_fetch_xor ((PTR), (VAL), (MO))
#define atomic_fetch_and(PTR,VAL) __atomic_fetch_and ((PTR), (VAL), __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit(PTR,VAL,MO) __atomic_fetch_and ((PTR), (VAL), (MO))
#define ATOMIC_FLAG_INIT { 0 }
#define atomic_flag_test_and_set(PTR) __atomic_test_and_set ((PTR), __ATOMIC_SEQ_CST)
#define atomic_flag_test_and_set_explicit(PTR,MO) __atomic_test_and_set ((PTR), (MO))
#define atomic_flag_clear(PTR) __atomic_clear ((PTR), __ATOMIC_SEQ_CST)
#define atomic_flag_clear_explicit(PTR,MO) __atomic_clear ((PTR), (MO))
#define INTERNAL_COMPAR_H
#define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
#define CMP_OPTIMIZABLE(type) BASIC_OP_UNREDEFINED_P(BOP_CMP, type ##_REDEFINED_OP_FLAG)
#define OPTIMIZED_CMP(a,b) ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(INTEGER)) ? (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) ? rb_str_cmp(a, b) : (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(FLOAT)) ? rb_float_cmp(a, b) : rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
#define INTERNAL_HASH_H
#define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE
#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
#define RHASH(obj) ((struct RHash *)(obj))
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
#pragma GCC visibility pop
#define INTERNAL_NUMERIC_H
#define INTERNAL_BIGNUM_H
#define BDIGIT unsigned int
#define SIZEOF_BDIGIT SIZEOF_INT
#define BDIGIT_DBL unsigned LONG_LONG
#define BDIGIT_DBL_SIGNED LONG_LONG
#define PRI_BDIGIT_PREFIX ""
#define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
#define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
#define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
#define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
#define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
#define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
#define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
#define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
#define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
#define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
#define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
#define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
#define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
#define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
#define RBIGNUM(obj) ((struct RBignum *)(obj))
#define BIGNUM_SIGN_BIT FL_USER1
#define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
#define BIGNUM_EMBED_LEN_NUMBITS 3
#define BIGNUM_EMBED_LEN_MASK (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
#define BIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+3)
#define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*RBIMPL_RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT)
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_BITS_H
#define HALF_LONG_MSB ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
#define SIGNED_INTEGER_TYPE_P(T) (0 > ((T)0)-1)
#define SIGNED_INTEGER_MIN(T) ((sizeof(T) == sizeof(int8_t)) ? ((T)INT8_MIN) : ((sizeof(T) == sizeof(int16_t)) ? ((T)INT16_MIN) : ((sizeof(T) == sizeof(int32_t)) ? ((T)INT32_MIN) : ((sizeof(T) == sizeof(int64_t)) ? ((T)INT64_MIN) : 0))))
#define SIGNED_INTEGER_MAX(T) ((T)(SIGNED_INTEGER_MIN(T) ^ ((T)~(T)0)))
#define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0)
#define MUL_OVERFLOW_P(a,b) __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
#define MUL_OVERFLOW_SIGNED_INTEGER_P(a,b,min,max) ( (a) == 0 ? 0 : (a) == -1 ? (b) < -(max) : (a) > 0 ? ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
#define MUL_OVERFLOW_FIXNUM_P(a,b) __extension__ ({ struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; __builtin_mul_overflow_p((a), (b), c.fixnum); })
#define MUL_OVERFLOW_LONG_LONG_P(a,b) MUL_OVERFLOW_P(a, b)
#define MUL_OVERFLOW_LONG_P(a,b) MUL_OVERFLOW_P(a, b)
#define MUL_OVERFLOW_INT_P(a,b) MUL_OVERFLOW_P(a, b)
#define bit_length(x) (unsigned int) (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : 128 - nlz_int128((uint128_t)(x)))
#define swap16 ruby_swap16
#define swap32 ruby_swap32
#define swap64 ruby_swap64
#define INTERNAL_FIXNUM_H
#define DLONG int128_t
#define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
#define ROUND_TO(mode,even,up,down) ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
#define ROUND_FUNC(mode,name) ROUND_TO(mode, name ##_half_even, name ##_half_up, name ##_half_down)
#define ROUND_CALL(mode,name,args) ROUND_TO(mode, name ##_half_even args, name ##_half_up args, name ##_half_down args)
#define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
#define roomof(x,y) (((x) + (y) - 1) / (y))
#define type_roomof(x,y) roomof(sizeof(x), sizeof(y))
#define RFLOAT(obj) ((struct RFloat *)(obj))
#define rb_float_value rb_float_value_inline
#define rb_float_new rb_float_new_inline
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#pragma GCC visibility push(default)
#pragma GCC visibility pop
#define INTERNAL_RANDOM_H
#define INTERNAL_STRUCT_H
#define RSTRUCT(obj) ((struct RStruct *)(obj))
#define RSTRUCT_LEN internal_RSTRUCT_LEN
#define RSTRUCT_SET internal_RSTRUCT_SET
#define RSTRUCT_GET internal_RSTRUCT_GET
#define RUBY_TOPLEVEL_VARIABLE_H
#define BIN(n) YARVINSN_ ##n
#define ASSERT_VM_INSTRUCTION_SIZE(array) STATIC_ASSERT(numberof_ ##array, numberof(array) == VM_INSTRUCTION_SIZE)
#define vm_check_canary(ec,sp)
#define vm_check_frame(a,b,c,d)
#define vm_push_frame_debug_counter_inc(ec,cfp,t)
#define ractor_incidental_shareable_p(cond,val) (!(cond) || rb_ractor_shareable_p(val))
#define ractor_object_incidental_shareable_p(obj,val) ractor_incidental_shareable_p(rb_ractor_shareable_p(obj), val)
#define ATTR_INDEX_NOT_SET (attr_index_t)-1
#define EQ_UNREDEFINED_P(t) BASIC_OP_UNREDEFINED_P(BOP_EQ, t ##_REDEFINED_OP_FLAG)
#undef EQ_UNREDEFINED_P
#define CHECK_CMP_NAN(a,b)
#define KW_SPECIFIED_BITS_MAX (32-1)
#define USE_OPT_HIST 0
#define CHECK_CFP_CONSISTENCY(func) (LIKELY(vm_cfp_consistent_p(ec, reg_cfp)) ? (void)0 : rb_bug(func ": cfp consistency error (%p, %p)", (void *)reg_cfp, (void *)(ec->cfp+1)))
#define VM_CALL_METHOD_ATTR(var,func,nohook) if (UNLIKELY(ruby_vm_event_flags & (RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN))) { EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, Qundef); var = func; EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, calling->recv, vm_cc_cme(cc)->def->original_id, vm_ci_mid(ci), vm_cc_cme(cc)->owner, (var)); } else { nohook; var = func; }
#define mexp_search_method vm_search_method_wrap
#define mexp_search_super vm_search_super_method
#define mexp_search_invokeblock vm_search_invokeblock
#define id_cmp idCmp
#undef id_cmp
#define IMEMO_CONST_CACHE_SHAREABLE IMEMO_FL_USER0
#define VM_TRACE_HOOK(target_event,val) do { if ((pc_events & (target_event)) & enabled_flags) { vm_trace_hook(ec, reg_cfp, pc, pc_events, (target_event), global_hooks, local_hooks_ptr, (val)); } } while (0)
#undef VM_TRACE_HOOK
#define id_mesg idMesg
include/ruby/ractor.h 0000644 00000021332 15040330601 0010604 0 ustar 00 #ifndef RUBY_RACTOR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RACTOR_H 1
/**
* @file
* @author Koichi Sasada
* @date Tue Nov 17 16:39:15 2020
* @copyright Copyright (C) 2020 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "internal/dllexport.h" /* RUBY_EXTERN is here */
#include "internal/fl_type.h" /* FL_TEST_RAW is here */
#include "internal/special_consts.h" /* RB_SPECIAL_CONSTS_P is here */
#include "internal/stdbool.h" /* bool is here */
#include "internal/value.h" /* VALUE is here */
/** Type that defines a ractor-local storage. */
struct rb_ractor_local_storage_type {
/**
* A function to mark a ractor-local storage.
*
* @param[out] ptr A ractor-local storage.
* @post Ruby objects inside of `ptr` are marked.
*/
void (*mark)(void *ptr);
/**
* A function to destruct a ractor-local storage.
*
* @param[out] ptr A ractor-local storage.
* @post `ptr` is not a valid pointer.
*/
void (*free)(void *ptr);
// TODO: update
};
/** (Opaque) struct that holds a ractor-local storage key. */
typedef struct rb_ractor_local_key_struct *rb_ractor_local_key_t;
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* `Ractor` class.
*
* @ingroup object
*/
RUBY_EXTERN VALUE rb_cRactor;
/**
* Queries the standard input of the current Ractor that is calling this
* function.
*
* @return An IO.
* @note This can be different from the process-global one.
*/
VALUE rb_ractor_stdin(void);
/**
* Queries the standard output of the current Ractor that is calling this
* function.
*
* @return An IO.
* @note This can be different from the process-global one.
*/
VALUE rb_ractor_stdout(void);
/**
* Queries the standard error of the current Ractor that is calling this
* function.
*
* @return An IO.
* @note This can be different from the process-global one.
*/
VALUE rb_ractor_stderr(void);
/**
* Assigns an IO to the standard input of the Ractor that is calling this
* function.
*
* @param[in] io An IO.
* @post `io` is the standard input of the current ractor.
* @post In case the calling Ractor is the main Ractor, it also updates
* the process global ::rb_stdin.
*/
void rb_ractor_stdin_set(VALUE io);
/**
* Assigns an IO to the standard output of the Ractor that is calling this
* function.
*
* @param[in] io An IO.
* @post `io` is the standard input of the current ractor.
* @post In case the calling Ractor is the main Ractor, it also updates
* the process global ::rb_stdout.
*/
void rb_ractor_stdout_set(VALUE io);
/**
* Assigns an IO to the standard error of the Ractor that is calling this
* function.
*
* @param[in] io An IO.
* @post `io` is the standard input of the current ractor.
* @post In case the calling Ractor is the main Ractor, it also updates
* the process global ::rb_stderr.
*/
void rb_ractor_stderr_set(VALUE io);
/**
* Issues a new key.
*
* @return A newly issued ractor-local storage key. Keys issued using this
* key can be associated to a Ruby object per Ractor.
*/
rb_ractor_local_key_t rb_ractor_local_storage_value_newkey(void);
/**
* Queries the key.
*
* @param[in] key A ractor-local storage key to lookup.
* @retval RUBY_Qnil No such key.
* @retval otherwise A value corresponds to `key` in the current Ractor.
* @note This cannot distinguish between a nonexistent key and a key
* exists and corresponds to ::RUBY_Qnil.
*/
VALUE rb_ractor_local_storage_value(rb_ractor_local_key_t key);
/**
* Queries the key.
*
* @param[in] key A ractor-local storage key to lookup.
* @param[out] val Return value buffer.
* @retval false `key` not found.
* @retval true `key` found.
* @post `val` is updated so that it has the value corresponds to `key`
* in the current Ractor.
*/
bool rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val);
/**
* Associates the passed value to the passed key.
*
* @param[in] key A ractor-local storage key.
* @param[in] val Arbitrary ruby object.
* @post `val` corresponds to `key` in the current Ractor.
*/
void rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val);
/**
* A type of ractor-local storage that destructs itself using ::ruby_xfree.
*
* @internal
*
* Why it is visible from 3rd party extension libraries is not obvious to
* @shyouhei.
*/
RUBY_EXTERN const struct rb_ractor_local_storage_type rb_ractor_local_storage_type_free;
/** @alias{rb_ractor_local_storage_type_free} */
#define RB_RACTOR_LOCAL_STORAGE_TYPE_FREE (&rb_ractor_local_storage_type_free)
/**
* Extended version of rb_ractor_local_storage_value_newkey(). It additionally
* takes the type of the issuing key.
*
* @param[in] type How the value associated with the issuing key should
* behave.
* @return A newly issued ractor-local storage key, of type `type`.
*/
rb_ractor_local_key_t rb_ractor_local_storage_ptr_newkey(const struct rb_ractor_local_storage_type *type);
/**
* Identical to rb_ractor_local_storage_value() except the return type.
*
* @param[in] key A ractor-local storage key to lookup.
* @retval NULL No such key.
* @retval otherwise A value corresponds to `key` in the current Ractor.
*/
void *rb_ractor_local_storage_ptr(rb_ractor_local_key_t key);
/**
* Identical to rb_ractor_local_storage_value_set() except the parameter type.
*
* @param[in] key A ractor-local storage key.
* @param[in] ptr A pointer that conforms `key`'s type.
* @post `ptr` corresponds to `key` in the current Ractor.
*/
void rb_ractor_local_storage_ptr_set(rb_ractor_local_key_t key, void *ptr);
/**
* Destructively transforms the passed object so that multiple Ractors can
* share it. What is a shareable object and what is not is a nuanced concept,
* and @ko1 says the definition can still change. However extension library
* authors might interest to learn how to use #RUBY_TYPED_FROZEN_SHAREABLE.
*
* @param[out] obj Arbitrary ruby object to modify.
* @exception rb_eRactorError Ractors cannot share `obj` by nature.
* @return Passed `obj`.
* @post Multiple Ractors can share `obj`.
*
* @internal
*
* In case an exception is raised, `obj` remains in an intermediate state where
* some of its part is frozen and others are not. @shyouhei is not sure if it
* is either an intended behaviour, current implementation limitation, or
* simply a bug. Note also that there is no way to "melt" a frozen object.
*/
VALUE rb_ractor_make_shareable(VALUE obj);
/**
* Identical to rb_ractor_make_shareable(), except it returns a (deep) copy of
* the passed one instead of modifying it in-place.
*
* @param[in] obj Arbitrary ruby object to duplicate.
* @exception rb_eRactorError Ractors cannot share `obj` by nature.
* @return A deep copy of `obj` which is sharable among Ractors.
*/
VALUE rb_ractor_make_shareable_copy(VALUE obj);
RBIMPL_SYMBOL_EXPORT_END()
/**
* Queries if the passed object has previously classified as shareable or not.
* This doesn't mean anything in practice... Objects can be shared later.
* Always use rb_ractor_shareable_p() instead.
*
* @param[in] obj Object in question.
* @retval RUBY_FL_SHAREABLE It once was shareable before.
* @retval 0 Otherwise.
*/
#define RB_OBJ_SHAREABLE_P(obj) FL_TEST_RAW((obj), RUBY_FL_SHAREABLE)
/**
* Queries if multiple Ractors can share the passed object or not. Ractors run
* without protecting each other. Sharing an object among them is basically
* dangerous, disabled by default. However there are objects that are
* extremely carefully implemented to be Ractor-safe; for instance integers
* have such property. This function can classify that.
*
* @param[in] obj Arbitrary ruby object.
* @retval true `obj` is capable of shared across ractors.
* @retval false `obj` cannot travel across ractor boundaries.
*/
static inline bool
rb_ractor_shareable_p(VALUE obj)
{
bool rb_ractor_shareable_p_continue(VALUE obj);
if (RB_SPECIAL_CONST_P(obj)) {
return true;
}
else if (RB_OBJ_SHAREABLE_P(obj)) {
return true;
}
else {
return rb_ractor_shareable_p_continue(obj);
}
}
#endif /* RUBY_RACTOR_H */
include/ruby/util.h 0000644 00000020361 15040330601 0010270 0 ustar 00 #ifndef RUBY_UTIL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_UTIL_H 1
/**
* @file
* @author $Author$
* @date Thu Mar 9 11:55:53 JST 1995
* @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning DO NOT ADD RANDOM GARBAGES IN THIS FILE! Contents of this file
* reside here for historical reasons. Find a right place for your
* API!
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h> /* size_t */
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nodiscard.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/defines.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/** an approximation of ceil(n * log10(2)), up to 65536 at least */
#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999)
/**
* Character to number mapping like `'a'` -> `10`, `'b'` -> `11` etc. For
* punctuation etc., the value is -1. "36" terminology comes from the fact
* that this is the table behind `str.to_i(36)`.
*/
RUBY_EXTERN const signed char ruby_digit36_to_number_table[];
/**
* Characters that Ruby accepts as hexadecimal digits. This is `/\h/` expanded
* into an array.
*/
RUBY_EXTERN const char ruby_hexdigits[];
/**
* Scans the passed string, assuming the string is a textual representation of
* an integer. Stops when encountering something non-digit for the passed
* base.
*
* @note This does not understand minus sign.
* @note This does not understand e.g. `0x` prefix.
* @note It is a failure to pass `0` to `base`, unlike ruby_strtoul().
* @param[in] str Target string of digits to interpret.
* @param[in] len Number of bytes of `str`, or -1 to detect `NUL`.
* @param[in] base Base, `2` to `36` inclusive.
* @param[out] retlen Return value buffer.
* @param[out] overflow Return value buffer.
* @return Interpreted numeric representation of `str`.
* @post `retlen` is the number of bytes scanned so far.
* @post `overflow` is set to true if the string represents something
* bigger than `ULONG_MAX`. Something meaningful still returns;
* which is the designed belabour of C's unsigned arithmetic.
*/
unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
/** @old{ruby_scan_oct} */
#define scan_oct(s,l,e) ((int)ruby_scan_oct((s),(l),(e)))
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL(())
/**
* Interprets the passed string as an octal unsigned integer. Stops when
* encounters something not understood.
*
* @param[in] str C string to scan.
* @param[in] len Length of `str`.
* @param[out] consumed Return value buffer.
* @return Parsed integer.
* @post `ret` is the number of characters read.
*
* @internal
*
* No consideration is made for integer overflows. As the return value is
* unsigned this function has fully defined behaviour, but you cannot know if
* there was an integer wrap-around or not.
*/
unsigned long ruby_scan_oct(const char *str, size_t len, size_t *consumed);
/** @old{ruby_scan_hex} */
#define scan_hex(s,l,e) ((int)ruby_scan_hex((s),(l),(e)))
RBIMPL_ATTR_NONNULL(())
/**
* Interprets the passed string a hexadecimal unsigned integer. Stops when
* encounters something not understood.
*
* @param[in] str C string to scan.
* @param[in] len Length of `str`.
* @param[out] ret Return value buffer.
* @return Parsed integer.
* @post `ret` is the number of characters read.
*
* @internal
*
* No consideration is made for integer overflows. As the return value is
* unsigned this function has fully defined behaviour, but you cannot know if
* there was an integer wrap-around or not.
*/
unsigned long ruby_scan_hex(const char *str, size_t len, size_t *ret);
/**
* Reentrant implementation of quick sort. If your system provides something
* (like C11 qsort_s), this is a thin wrapper of that routine. Otherwise
* resorts to our own version.
*/
#ifdef HAVE_GNU_QSORT_R
# define ruby_qsort qsort_r
#else
void ruby_qsort(void *, const size_t, const size_t,
int (*)(const void *, const void *, void *), void *);
#endif
RBIMPL_ATTR_NONNULL((1))
/**
* Sets an environment variable. In case of POSIX this is a wrapper of
* `setenv(3)`. But there are systems which lack one. We try hard emulating.
*
* @param[in] key An environment variable.
* @param[in] val A value to be associated with `key`, or 0.
* @exception rb_eSystemCallError `setenv(3)` failed for some reason.
* @post Environment variable `key` is created if necessary. Its value
* is updated to be `val`.
*/
void ruby_setenv(const char *key, const char *val);
RBIMPL_ATTR_NONNULL(())
/**
* Deletes the passed environment variable, if any.
*
* @param[in] key An environment variable.
* @exception rb_eSystemCallError `unsetenv(3)` failed for some reason.
* @post Environment variable `key` does not exist.
*/
void ruby_unsetenv(const char *key);
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_NONNULL(())
/**
* This is our own version of `strdup(3)` that uses ruby_xmalloc() instead of
* system malloc (benefits our GC).
*
* @param[in] str Target C string to duplicate.
* @return An allocated C string holding the identical contents.
* @note Return value must be discarded using ruby_xfree().
*/
char *ruby_strdup(const char *str);
#undef strdup
/**
* @alias{ruby_strdup}
*
* @internal
*
* @shyouhei doesn't think it is a wise idea. ruby_strdup()'s return value
* must be passed to ruby_xfree(), but this macro makes it almost impossible.
*/
#define strdup(s) ruby_strdup(s)
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
/**
* This is our own version of `getcwd(3)` that uses ruby_xmalloc() instead of
* system malloc (benefits our GC).
*
* @return An allocated C string holding the process working directory.
* @note Return value must be discarded using ruby_xfree().
*/
char *ruby_getcwd(void);
RBIMPL_ATTR_NONNULL((1))
/**
* Our own locale-insensitive version of `strtod(3)`. The conversion is done
* as if the current locale is set to the "C" locale, no matter actual runtime
* locale settings.
*
* @param[in] str Decimal or hexadecimal representation of a floating
* point number.
* @param[out] endptr NULL, or an arbitrary pointer (overwritten on return).
* @return Converted number.
* @post If `endptr` is not NULL, it is updated to point the first such
* byte where conversion failed.
* @note This function sets `errno` on failure.
* - `ERANGE`: Converted integer is out of range of `double`.
* @see William D. Clinger, "How to Read Floating Point Numbers
* Accurately" in Proc. ACM SIGPLAN '90, pp. 92-101.
* https://doi.org/10.1145/93542.93557
*/
double ruby_strtod(const char *str, char **endptr);
#undef strtod
/** @alias{ruby_strtod} */
#define strtod(s,e) ruby_strtod((s),(e))
RBIMPL_ATTR_NONNULL((2))
/**
* Scans the passed string, with calling the callback function every time it
* encounters a "word". A word here is a series of characters separated by
* either a space (of IEEE 1003.1 section 7.3.1.1), or a `','`.
*
* @param[in] str Target string to split into each words.
* @param[in] func Callback function.
* @param[in,out] argv Passed as-is to `func`.
*/
void ruby_each_words(const char *str, void (*func)(const char *word, int len, void *argv), void *argv);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_UTIL_H */
include/ruby/re.h 0000644 00000012703 15040330601 0007722 0 ustar 00 #ifndef RUBY_RE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RE_H 1
/**
* @file
* @author $Author$
* @date Thu Sep 30 14:18:32 JST 1993
* @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/config.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <stdio.h>
#include "ruby/regex.h"
#include "ruby/internal/core/rmatch.h"
#include "ruby/internal/dllexport.h"
struct re_registers; /* Defined in onigmo.h */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Creates a new instance of ::rb_cRegexp. It can be seen as a specialised
* version of rb_reg_new_str() where it does not take options.
*
* @param[in] str Source code in String.
* @return Allocated new instance of ::rb_cRegexp.
*/
VALUE rb_reg_regcomp(VALUE str);
/**
* Runs the passed regular expression over the passed string. Unlike
* rb_reg_search() this function also takes position and direction of the
* search, which make it possible for this function to run from in middle of
* the string.
*
* @param[in] re Regular expression to execute.
* @param[in] str Target string to search.
* @param[in] pos Offset in `str` to start searching, in bytes.
* @param[in] dir `pos`' direction; 0 means left-to-right, 1 for
* the opposite.
* @exception rb_eArgError `re` is broken.
* @exception rb_eRegexpError `re` is malformed.
* @retval -1 Match failed.
* @retval otherwise Offset of first such byte where match happened.
* @post `Regexp.last_match` is updated.
* @post `$&`, `$~`, etc., are updated.
*
* @internal
*
* Distinction between raising ::rb_eArgError and ::rb_eRegexpError is not
* obvious, at least to @shyouhei.
*/
long rb_reg_search(VALUE re, VALUE str, long pos, int dir);
/**
* Substitution. This is basically the implementation of `String#sub`. Also
* `String#gsub` repeatedly calls this function.
*
* @param[in] repl Replacement string, e.g. `"\\1\\2"`
* @param[in] src Source string, to be replaced.
* @param[in] regs Matched data generated by applying `rexp` to `src`.
* @param[in] rexp Regular expression.
* @return A substituted string.
*
* @internal
*
* This function does not check for encoding compatibility. `String#sub!`
* etc. employ their own checker.
*
* `regs` should have been `const struct re_registers *` because it is read
* only. Kept as-is for compatibility.
*/
VALUE rb_reg_regsub(VALUE repl, VALUE src, struct re_registers *regs, VALUE rexp);
/**
* Tell us if this is a wrong idea, but it seems this function has no usage at
* all. Just remains here for theoretical backwards compatibility.
*
* @param[in] re Regular expression to execute.
* @param[in] str Target string to search.
* @param[in] pos Offset in `str` to start searching, in bytes.
* @param[in] dir `pos`' direction; 0 means left-to-right, 1 for
* the opposite.
* @return Adjusted nearest offset to `pos` inside of `str`, where is a
* character boundary.
*
*/
long rb_reg_adjust_startpos(VALUE re, VALUE str, long pos, int dir);
/**
* Escapes any characters that would have special meaning in a regular
* expression.
*
* @param[in] str Target string to escape.
* @return A copy of `str` whose contents are escaped.
*/
VALUE rb_reg_quote(VALUE str);
/**
* Exercises various checks and preprocesses so that the given regular
* expression can be applied to the given string. The preprocess here includes
* (but not limited to) for instance encoding conversion.
*
* @param[in] re Target regular expression.
* @param[in] str What `re` is about to run on.
* @exception rb_eArgError `re` does not fit for `str`.
* @exception rb_eEncCompatError `re` and `str` are incompatible.
* @exception rb_eRegexpError `re` is malformed.
* @return A preprocessesed pattern buffer ready to be applied to `str`.
* @note The return value is manages by our GC. Don't free.
*
* @internal
*
* The return type, `regex_t *`, is defined in `<ruby/onigmo.h>`, _and_
* _conflicts_ with POSIX's `<regex.h>`. We can no longer save the situation
* at this point. Just don't mix the two.
*/
regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
/**
* Duplicates a match data. This is roughly the same as `onig_region_copy()`,
* except it tries to GC when there is not enough memory.
*
* @param[out] dst Target registers to fill.
* @param[in] src Source registers to duplicate.
* @exception rb_eNoMemError Not enough memory.
* @retval 0 Successful
* @retval ONIGERR_MEMORY Not enough memory, even after GC (unlikely).
* @post `dst` has identical contents to `src`.
*
* @internal
*
* It seems this function is here for `ext/strscan` and nothing else.
*/
int rb_reg_region_copy(struct re_registers *dst, const struct re_registers *src);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_RE_H */
include/ruby/thread.h 0000644 00000022215 15040330601 0010562 0 ustar 00 #ifndef RUBY_THREAD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_H 1
/**
* @file
* @author $Author: matz $
* @date Tue Jul 10 17:35:43 JST 2012
* @copyright Copyright (C) 2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/intern/thread.h" /* rb_unblock_function_t */
#include "ruby/internal/dllexport.h"
/**
* @name Flags for rb_nogvl()
*
* @{
*/
/**
* Passing this flag to rb_nogvl() prevents it from checking interrupts.
* Interrupts can impact your program negatively. For instance consider
* following callback function:
*
* ```CXX
* static inline int fd; // set elsewhere.
* static inline auto callback(auto buf) {
* auto tmp = ruby_xmalloc(BUFSIZ);
* auto ret = ruby_xmalloc(sizeof(ssize_t)); // (a)
* auto n = read(fd, tmp, BUFSIZ); // (b)
* memcpy(buf, tmp, n); // (c)
* memcpy(ret, n, sizeof(n));
* ruby_xfree(tmp);
* return ret;
* }
* ```
*
* Here, if it gets interrupted at (a) or (b), `read(2)` is cancelled and this
* function leaks memory (which is not a good thing of course, but...). But if
* it gets interrupted at (c), where `read(2)` is already done, interruption is
* way more catastrophic because what was read gets lost. To reroute this kind
* of problem you should set this flag. And check interrupts elsewhere at your
* own risk.
*/
#define RB_NOGVL_INTR_FAIL (0x1)
/**
* Passing this flag to rb_nogvl() indicates that the passed UBF is
* async-signal-safe. An UBF could be async safe, and that makes things
* simpler. However async unsafe UBFs are just okay. If unsure, you can
* safely leave it unspecified.
*
* @internal
*
* This makes sense only in case of POSIX threads.
*/
#define RB_NOGVL_UBF_ASYNC_SAFE (0x2)
/** @} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((1))
/**
* (Re-)acquires the GVL. This manoeuvre makes it possible for an out-of-GVL
* routine to one-shot call a ruby method.
*
* What this function does:
*
* 1. Blocks until it acquires the GVL.
* 2. Calls the passed function.
* 3. Releases the GVL.
* 4. Returns what was returned form the passed function.
*
* @param[in] func What to call with GVL.
* @param[in,out] data1 Passed as-is to `func`.
* @return What was returned from `func`.
* @warning `func` must not return a Ruby object. If it did such return
* value would escape from GC's scope; would not be marked.
* @warning Global escapes from this function just yield whatever fatal
* undefined behaviours. You must make sure that `func` does
* not raise, by properly rescuing everything using
* e.g. rb_protect().
* @warning You cannot convert a non-Ruby thread into a Ruby thread
* using this API. This function makes sense only from inside
* of a rb_thread_call_without_gvl()'s callback.
*/
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
RBIMPL_ATTR_NONNULL((1))
/**
* Allows the passed function to run in parallel with other Ruby threads.
*
* What this function does:
*
* 1. Checks (and handles) pending interrupts.
* 2. Releases the GVL. (Others can run here in parallel...)
* 3. Calls the passed function.
* 4. Blocks until it re-acquires the GVL.
* 5. Checks interrupts that happened between 2 to 4.
*
* In case other threads interfaced with this thread using rb_thread_kill()
* etc., the passed UBF is additionally called. See ::rb_unblock_function_t
* for details.
*
* Unlike rb_thread_call_without_gvl2() this function also reacts to signals
* etc.
*
* @param[in] func A function to call without GVL.
* @param[in,out] data1 Passed as-is to `func`.
* @param[in] ubf An UBF to cancel `func`.
* @param[in,out] data2 Passed as-is to `ubf`.
* @return What `func` returned, or 0 in case `ubf` cancelled `func`.
* @warning You cannot use most of Ruby C APIs like calling methods or
* raising exceptions from any of the functions passed to it.
* If that is dead necessary use rb_thread_call_with_gvl() to
* re-acquire the GVL.
* @warning In short, this API is difficult. @ko1 recommends you to use
* other ways if any. We lack experiences to use this API. If
* you find any corner cases etc., please report it to the
* devs.
* @warning Releasing and re-acquiring the GVL are expensive operations.
* For a short-running `func`, it might be faster to just call
* `func` with blocking everything else. Be sure to benchmark
* your code to see if it is actually worth releasing the GVL.
*/
void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_thread_call_without_gvl(), except it does not interface with
* signals etc. As described in #RB_NOGVL_INTR_FAIL, interrupts can hurt you.
* In case this function detects an interrupt, it returns immediately. You can
* record progress of your callback and check it after returning from this
* function.
*
* What this function does:
*
* 1. Checks for pending interrupts and if any, just returns.
* 2. Releases the GVL. (Others can run here in parallel...)
* 3. Calls the passed function.
* 4. Blocks until it re-acquires the GVL.
*
* @param[in] func A function to call without GVL.
* @param[in,out] data1 Passed as-is to `func`.
* @param[in] ubf An UBF to cancel `func`.
* @param[in,out] data2 Passed as-is to `ubf`.
* @return What `func` returned, or 0 in case `func` did not return.
*/
void *rb_thread_call_without_gvl2(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
/*
* XXX: unstable/unapproved - out-of-tree code should NOT not depend
* on this until it hits Ruby 2.6.1
*/
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_thread_call_without_gvl(), except it additionally takes
* "flags" that change the behaviour.
*
* @param[in] func A function to call without GVL.
* @param[in,out] data1 Passed as-is to `func`.
* @param[in] ubf An UBF to cancel `func`.
* @param[in,out] data2 Passed as-is to `ubf`.
* @param[in] flags Flags.
* @return What `func` returned, or 0 in case `func` did not return.
*/
void *rb_nogvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2,
int flags);
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_AFTER 0x01
/**
* @private
* @deprecated It seems even in the old days it made no sense...?
*/
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_
#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0 /** thread started */
#define RUBY_INTERNAL_THREAD_EVENT_READY 1 << 1 /** acquiring GVL */
#define RUBY_INTERNAL_THREAD_EVENT_RESUMED 1 << 2 /** acquired GVL */
#define RUBY_INTERNAL_THREAD_EVENT_SUSPENDED 1 << 3 /** released GVL */
#define RUBY_INTERNAL_THREAD_EVENT_EXITED 1 << 4 /** thread terminated */
#define RUBY_INTERNAL_THREAD_EVENT_MASK 0xff /** All Thread events */
typedef void rb_internal_thread_event_data_t; // for future extension.
typedef void (*rb_internal_thread_event_callback)(rb_event_flag_t event,
const rb_internal_thread_event_data_t *event_data,
void *user_data);
typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t;
/**
* Registers a thread event hook function.
*
* @param[in] func A callback.
* @param[in] events A set of events that `func` should run.
* @param[in] data Passed as-is to `func`.
* @return An opaque pointer to the hook, to unregister it later.
* @note This functionality is a noop on Windows.
* @warning This function MUST not be called from a thread event callback.
*/
rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook(
rb_internal_thread_event_callback func, rb_event_flag_t events,
void *data);
/**
* Unregister the passed hook.
*
* @param[in] hook. The hook to unregister.
* @return Wether the hook was found and unregistered.
* @note This functionality is a noop on Windows.
* @warning This function MUST not be called from a thread event callback.
*/
bool rb_internal_thread_remove_event_hook(
rb_internal_thread_event_hook_t * hook);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_THREAD_H */
include/ruby/config-x86_64.h 0000644 00000033431 15040330601 0011516 0 ustar 00 #ifndef INCLUDE_RUBY_CONFIG_H
#define INCLUDE_RUBY_CONFIG_H 1
/* confdefs.h */
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_PTHREAD_SEMANTICS 1
#define _TANDEM_SOURCE 1
#define RUBY_SYMBOL_EXPORT_BEGIN _Pragma("GCC visibility push(default)")
#define RUBY_SYMBOL_EXPORT_END _Pragma("GCC visibility pop")
#define HAVE_STMT_AND_DECL_IN_EXPR 1
#define HAVE_PTHREAD_H 1
#define _REENTRANT 1
#define _THREAD_SAFE 1
#define HAVE_LIBPTHREAD 1
#define THREAD_IMPL_H "thread_pthread.h"
#define THREAD_IMPL_SRC "thread_pthread.c"
#define HAVE_LIBCRYPT 1
#define HAVE_LIBDL 1
#define HAVE_DIRENT_H 1
#define HAVE__BOOL 1
#define HAVE_STDBOOL_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_GRP_H 1
#define HAVE_FCNTL_H 1
#define HAVE_FLOAT_H 1
#define HAVE_LANGINFO_H 1
#define HAVE_LIMITS_H 1
#define HAVE_LOCALE_H 1
#define HAVE_MALLOC_H 1
#define HAVE_PWD_H 1
#define HAVE_SANITIZER_ASAN_INTERFACE_H 1
#define HAVE_STDALIGN_H 1
#define HAVE_STDIO_H 1
#define HAVE_SYS_EVENTFD_H 1
#define HAVE_SYS_FCNTL_H 1
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_PRCTL_H 1
#define HAVE_SYS_RANDOM_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_SENDFILE_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_SYSCALL_H 1
#define HAVE_SYS_SYSMACROS_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_UIO_H 1
#define HAVE_SYSCALL_H 1
#define HAVE_TIME_H 1
#define HAVE_UCONTEXT_H 1
#define HAVE_UTIME_H 1
#define HAVE_STDATOMIC_H 1
#define HAVE_X86INTRIN_H 1
#if defined(__x86_64__)
#define HAVE_X86INTRIN_H 1
#endif
#define HAVE_GMP_H 1
#define HAVE_LIBGMP 1
#define HAVE_TYPEOF 1
#define restrict __restrict
#define HAVE_LONG_LONG 1
#define HAVE_OFF_T 1
#define SIZEOF_INT 4
#define SIZEOF_SHORT 2
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF___INT64 0
#define SIZEOF___INT128 16
#define SIZEOF_OFF_T 8
#define SIZEOF_VOIDP 8
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8
#define SIZEOF_TIME_T 8
#define SIZEOF_CLOCK_T 8
#define PACKED_STRUCT(x) x __attribute__((packed))
#define USE_UNALIGNED_MEMBER_ACCESS 1
#define PRI_LL_PREFIX "ll"
#define HAVE_PID_T 1
#define rb_pid_t pid_t
#define SIGNEDNESS_OF_PID_T -1
#define PIDT2NUM(v) INT2NUM(v)
#define NUM2PIDT(v) NUM2INT(v)
#define PRI_PIDT_PREFIX PRI_INT_PREFIX
#define HAVE_UID_T 1
#define rb_uid_t uid_t
#define SIGNEDNESS_OF_UID_T +1
#define UIDT2NUM(v) UINT2NUM(v)
#define NUM2UIDT(v) NUM2UINT(v)
#define PRI_UIDT_PREFIX PRI_INT_PREFIX
#define HAVE_GID_T 1
#define rb_gid_t gid_t
#define SIGNEDNESS_OF_GID_T +1
#define GIDT2NUM(v) UINT2NUM(v)
#define NUM2GIDT(v) NUM2UINT(v)
#define PRI_GIDT_PREFIX PRI_INT_PREFIX
#define HAVE_TIME_T 1
#define rb_time_t time_t
#define SIGNEDNESS_OF_TIME_T -1
#define TIMET2NUM(v) LONG2NUM(v)
#define NUM2TIMET(v) NUM2LONG(v)
#define PRI_TIMET_PREFIX PRI_LONG_PREFIX
#define HAVE_DEV_T 1
#define rb_dev_t dev_t
#define SIGNEDNESS_OF_DEV_T +1
#define DEVT2NUM(v) ULONG2NUM(v)
#define NUM2DEVT(v) NUM2ULONG(v)
#define PRI_DEVT_PREFIX PRI_LONG_PREFIX
#define HAVE_MODE_T 1
#define rb_mode_t mode_t
#define SIGNEDNESS_OF_MODE_T +1
#define MODET2NUM(v) UINT2NUM(v)
#define NUM2MODET(v) NUM2UINT(v)
#define PRI_MODET_PREFIX PRI_INT_PREFIX
#define HAVE_RLIM_T 1
#define rb_rlim_t rlim_t
#define SIGNEDNESS_OF_RLIM_T +1
#define RLIM2NUM(v) ULONG2NUM(v)
#define NUM2RLIM(v) NUM2ULONG(v)
#define PRI_RLIM_PREFIX PRI_LONG_PREFIX
#define HAVE_OFF_T 1
#define rb_off_t off_t
#define SIGNEDNESS_OF_OFF_T -1
#define OFFT2NUM(v) LONG2NUM(v)
#define NUM2OFFT(v) NUM2LONG(v)
#define PRI_OFFT_PREFIX PRI_LONG_PREFIX
#define HAVE_CLOCKID_T 1
#define rb_clockid_t clockid_t
#define SIGNEDNESS_OF_CLOCKID_T -1
#define CLOCKID2NUM(v) INT2NUM(v)
#define NUM2CLOCKID(v) NUM2INT(v)
#define PRI_CLOCKID_PREFIX PRI_INT_PREFIX
#define HAVE_VA_ARGS_MACRO 1
#define HAVE__ALIGNOF 1
#define CONSTFUNC(x) __attribute__ ((__const__)) x
#define PUREFUNC(x) __attribute__ ((__pure__)) x
#define NORETURN(x) __attribute__ ((__noreturn__)) x
#define DEPRECATED(x) __attribute__ ((__deprecated__)) x
#define DEPRECATED_BY(n,x) __attribute__ ((__deprecated__("by "#n))) x
#define NOINLINE(x) __attribute__ ((__noinline__)) x
#define ALWAYS_INLINE(x) __attribute__ ((__always_inline__)) x
#define NO_SANITIZE(san, x) __attribute__ ((__no_sanitize__(san))) x
#define NO_SANITIZE_ADDRESS(x) __attribute__ ((__no_sanitize_address__)) x
#define NO_ADDRESS_SAFETY_ANALYSIS(x) __attribute__ ((__no_address_safety_analysis__)) x
#define WARN_UNUSED_RESULT(x) __attribute__ ((__warn_unused_result__)) x
#define MAYBE_UNUSED(x) __attribute__ ((__unused__)) x
#define ERRORFUNC(mesg,x) __attribute__ ((__error__ mesg)) x
#define WARNINGFUNC(mesg,x) __attribute__ ((__warning__ mesg)) x
#define WEAK(x) __attribute__ ((__weak__)) x
#define HAVE_FUNC_WEAK 1
#define RUBY_CXX_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
#define HAVE_NULLPTR 1
#define FUNC_UNOPTIMIZED(x) __attribute__ ((__optimize__("O0"))) x
#define FUNC_MINIMIZED(x) __attribute__ ((__optimize__("-Os","-fomit-frame-pointer"))) x
#define HAVE_ATTRIBUTE_FUNCTION_ALIAS 1
#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) type prot __attribute__((alias(#name)));
#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) RUBY_ALIAS_FUNCTION_TYPE(void, prot, name, args)
#define HAVE_GCC_ATOMIC_BUILTINS 1
#define HAVE_GCC_SYNC_BUILTINS 1
#define HAVE___BUILTIN_UNREACHABLE 1
#define RUBY_FUNC_EXPORTED __attribute__ ((__visibility__("default"))) extern
#define RUBY_FUNC_NONNULL(n,x) __attribute__ ((__nonnull__(n))) x
#define RUBY_FUNCTION_NAME_STRING __func__
#define ENUM_OVER_INT 1
#define HAVE_DECL_SYS_NERR 1
#define HAVE_DECL_GETENV 1
#define SIZEOF_SIZE_T 8
#define SIZEOF_PTRDIFF_T 8
#define SIZEOF_DEV_T 8
#define PRI_SIZE_PREFIX "z"
#define PRI_PTRDIFF_PREFIX "t"
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
#define HAVE_STRUCT_STAT_ST_RDEV 1
#define SIZEOF_STRUCT_STAT_ST_SIZE SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_BLOCKS SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_INO SIZEOF_LONG
#define SIZEOF_STRUCT_STAT_ST_DEV SIZEOF_DEV_T
#define SIZEOF_STRUCT_STAT_ST_RDEV SIZEOF_DEV_T
#define HAVE_STRUCT_STAT_ST_ATIM 1
#define HAVE_STRUCT_STAT_ST_MTIM 1
#define HAVE_STRUCT_STAT_ST_CTIM 1
#define HAVE_STRUCT_STATX_STX_BTIME 1
#define HAVE_STRUCT_TIMEVAL 1
#define SIZEOF_STRUCT_TIMEVAL_TV_SEC SIZEOF_TIME_T
#define HAVE_STRUCT_TIMESPEC 1
#define HAVE_STRUCT_TIMEZONE 1
#define HAVE_RB_FD_INIT 1
#define HAVE_INT8_T 1
#define SIZEOF_INT8_T 1
#define HAVE_UINT8_T 1
#define SIZEOF_UINT8_T 1
#define HAVE_INT16_T 1
#define SIZEOF_INT16_T 2
#define HAVE_UINT16_T 1
#define SIZEOF_UINT16_T 2
#define HAVE_INT32_T 1
#define SIZEOF_INT32_T 4
#define HAVE_UINT32_T 1
#define SIZEOF_UINT32_T 4
#define HAVE_INT64_T 1
#define SIZEOF_INT64_T 8
#define HAVE_UINT64_T 1
#define SIZEOF_UINT64_T 8
#define HAVE_INT128_T 1
#define int128_t __int128
#define SIZEOF_INT128_T SIZEOF___INT128
#define HAVE_UINT128_T 1
#define uint128_t unsigned __int128
#define SIZEOF_UINT128_T SIZEOF___INT128
#define HAVE_INTPTR_T 1
#define SIZEOF_INTPTR_T 8
#define HAVE_UINTPTR_T 1
#define SIZEOF_UINTPTR_T 8
#define HAVE_SSIZE_T 1
#define SIZEOF_SSIZE_T 8
#define STACK_END_ADDRESS __libc_stack_end
#define GETGROUPS_T gid_t
#define HAVE_ALLOCA_H 1
#define HAVE_ALLOCA 1
#define HAVE_DUP 1
#define HAVE_DUP2 1
#define HAVE_ACOSH 1
#define HAVE_CBRT 1
#define HAVE_CRYPT 1
#define HAVE_ERF 1
#define HAVE_EXPLICIT_BZERO 1
#define HAVE_FFS 1
#define HAVE_FLOCK 1
#define HAVE_HYPOT 1
#define HAVE_LGAMMA_R 1
#define HAVE_MEMMOVE 1
#define HAVE_NAN 1
#define HAVE_NEXTAFTER 1
#define HAVE_STRCHR 1
#define HAVE_STRERROR 1
#define HAVE_STRSTR 1
#define HAVE_TGAMMA 1
#define HAVE_ISFINITE 1
#define SPT_TYPE SPT_REUSEARGV
#define HAVE_SIGNBIT 1
#define HAVE_FORK 1
#define HAVE_VFORK 1
#define HAVE_WORKING_VFORK 1
#define HAVE_WORKING_FORK 1
#define HAVE__LONGJMP 1
#define HAVE_ATAN2L 1
#define HAVE_ATAN2F 1
#define HAVE_DECL_ATOMIC_SIGNAL_FENCE 1
#define HAVE_CHMOD 1
#define HAVE_CHOWN 1
#define HAVE_CHROOT 1
#define HAVE_CLOCK_GETTIME 1
#define HAVE_COPY_FILE_RANGE 1
#define HAVE_COSH 1
#define HAVE_CRYPT_R 1
#define HAVE_DIRFD 1
#define HAVE_DL_ITERATE_PHDR 1
#define HAVE_DLOPEN 1
#define HAVE_DLADDR 1
#define HAVE_DUP3 1
#define HAVE_EACCESS 1
#define HAVE_ENDGRENT 1
#define HAVE_EVENTFD 1
#define HAVE_EXECL 1
#define HAVE_EXECLE 1
#define HAVE_EXECV 1
#define HAVE_EXECVE 1
#define HAVE_FCHMOD 1
#define HAVE_FCHOWN 1
#define HAVE_FCNTL 1
#define HAVE_FDATASYNC 1
#define HAVE_FDOPENDIR 1
#define HAVE_FMOD 1
#define HAVE_FSTATAT 1
#define HAVE_FSYNC 1
#define HAVE_FTRUNCATE 1
#define HAVE_FTRUNCATE64 1
#define HAVE_GETCWD 1
#define HAVE_GETEGID 1
#define HAVE_GETENTROPY 1
#define HAVE_GETEUID 1
#define HAVE_GETGID 1
#define HAVE_GETGRNAM 1
#define HAVE_GETGRNAM_R 1
#define HAVE_GETGROUPS 1
#define HAVE_GETLOGIN 1
#define HAVE_GETLOGIN_R 1
#define HAVE_GETPGID 1
#define HAVE_GETPGRP 1
#define HAVE_GETPPID 1
#define HAVE_GETPRIORITY 1
#define HAVE_GETPWNAM 1
#define HAVE_GETPWNAM_R 1
#define HAVE_GETPWUID 1
#define HAVE_GETPWUID_R 1
#define HAVE_GETRANDOM 1
#define HAVE_GETRESGID 1
#define HAVE_GETRESUID 1
#define HAVE_GETRLIMIT 1
#define HAVE_GETSID 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_GETUID 1
#define HAVE_GMTIME_R 1
#define HAVE_GRANTPT 1
#define HAVE_INITGROUPS 1
#define HAVE_IOCTL 1
#define HAVE_KILL 1
#define HAVE_KILLPG 1
#define HAVE_LCHOWN 1
#define HAVE_LINK 1
#define HAVE_LLABS 1
#define HAVE_LOCKF 1
#define HAVE_LOG2 1
#define HAVE_LSTAT 1
#define HAVE_LUTIMES 1
#define HAVE_MALLOC_USABLE_SIZE 1
#define HAVE_MBLEN 1
#define HAVE_MEMALIGN 1
#define HAVE_WRITEV 1
#define HAVE_MEMRCHR 1
#define HAVE_MEMMEM 1
#define HAVE_MKFIFO 1
#define HAVE_MKNOD 1
#define HAVE_MKTIME 1
#define HAVE_MMAP 1
#define HAVE_MREMAP 1
#define HAVE_OPENAT 1
#define HAVE_PCLOSE 1
#define HAVE_PIPE 1
#define HAVE_PIPE2 1
#define HAVE_POLL 1
#define HAVE_POPEN 1
#define HAVE_POSIX_FADVISE 1
#define HAVE_POSIX_MADVISE 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_PPOLL 1
#define HAVE_PREAD 1
#define HAVE_PWRITE 1
#define HAVE_QSORT_R 1
#define HAVE_READLINK 1
#define HAVE_REALPATH 1
#define HAVE_ROUND 1
#define HAVE_SCHED_GETAFFINITY 1
#define HAVE_SEEKDIR 1
#define HAVE_SENDFILE 1
#define HAVE_SETEGID 1
#define HAVE_SETENV 1
#define HAVE_SETEUID 1
#define HAVE_SETGID 1
#define HAVE_SETGROUPS 1
#define HAVE_SETPGID 1
#define HAVE_SETPGRP 1
#define HAVE_SETREGID 1
#define HAVE_SETRESGID 1
#define HAVE_SETRESUID 1
#define HAVE_SETREUID 1
#define HAVE_SETRLIMIT 1
#define HAVE_SETSID 1
#define HAVE_SETUID 1
#define HAVE_SHUTDOWN 1
#define HAVE_SIGACTION 1
#define HAVE_SIGALTSTACK 1
#define HAVE_SIGPROCMASK 1
#define HAVE_SINH 1
#define HAVE_SYMLINK 1
#define HAVE_SYSCALL 1
#define HAVE_SYSCONF 1
#define HAVE_SYSTEM 1
#define HAVE_TANH 1
#define HAVE_TELLDIR 1
#define HAVE_TIMEGM 1
#define HAVE_TIMES 1
#define HAVE_TRUNCATE 1
#define HAVE_TRUNCATE64 1
#define HAVE_TZSET 1
#define HAVE_UMASK 1
#define HAVE_UNSETENV 1
#define HAVE_UTIMENSAT 1
#define HAVE_UTIMES 1
#define HAVE_WAIT4 1
#define HAVE_WAITPID 1
#define HAVE_STATX 1
#define HAVE_CRYPT_H 1
#define HAVE_STRUCT_CRYPT_DATA_INITIALIZED 1
#define HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN 1
#define HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED 1
#define HAVE_BUILTIN___BUILTIN_BSWAP16 1
#define HAVE_BUILTIN___BUILTIN_BSWAP32 1
#define HAVE_BUILTIN___BUILTIN_BSWAP64 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNT 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNTLL 1
#define HAVE_BUILTIN___BUILTIN_CLZ 1
#define HAVE_BUILTIN___BUILTIN_CLZL 1
#define HAVE_BUILTIN___BUILTIN_CLZLL 1
#define HAVE_BUILTIN___BUILTIN_CTZ 1
#define HAVE_BUILTIN___BUILTIN_CTZLL 1
#define HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P 1
#define HAVE_BUILTIN___BUILTIN_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P 1
#define HAVE_BUILTIN___BUILTIN_TRAP 1
#define HAVE_BUILTIN___BUILTIN_EXPECT 1
#define HAVE_GNU_QSORT_R 1
#define ATAN2_INF_C99 1
#define HAVE_CLOCK_GETRES 1
#define HAVE_LIBRT 1
#define HAVE_LIBRT 1
#define HAVE_TIMER_CREATE 1
#define HAVE_TIMER_SETTIME 1
#define HAVE_STRUCT_TM_TM_ZONE 1
#define HAVE_TM_ZONE 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_DAYLIGHT 1
#define NEGATIVE_TIME_T 1
#define POSIX_SIGNAL 1
#define HAVE_SIG_T 1
#define RSHIFT(x,y) ((x)>>(int)(y))
#define USE_COPY_FILE_RANGE 1
#define HAVE__SC_CLK_TCK 1
#define STACK_GROW_DIRECTION -1
#define COROUTINE_H "coroutine/amd64/Context.h"
#define HAVE_SCHED_YIELD 1
#define HAVE_PTHREAD_ATTR_SETINHERITSCHED 1
#define HAVE_PTHREAD_ATTR_GETSTACK 1
#define HAVE_PTHREAD_ATTR_GETGUARDSIZE 1
#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
#define HAVE_PTHREAD_SETNAME_NP 1
#define HAVE_PTHREAD_SIGMASK 1
#define HAVE_PTHREAD_GETATTR_NP 1
#define SET_CURRENT_THREAD_NAME(name) pthread_setname_np(pthread_self(), name)
#define SET_ANOTHER_THREAD_NAME(thid,name) pthread_setname_np(thid, name)
#define DEFINE_MCONTEXT_PTR(mc, uc) mcontext_t *mc = &(uc)->uc_mcontext
#define HAVE_GETCONTEXT 1
#define HAVE_SETCONTEXT 1
#define HAVE_SYS_USER_H 1
#define HAVE_CONST_PAGE_SIZE 1
#define IOCTL_REQ_TYPE unsigned long
#define NUM2IOCTLREQ(num) NUM2ULONG(num)
#define USE_ELF 1
#define HAVE_ELF_H 1
#define HAVE_LIBZ 1
#define HAVE_BACKTRACE 1
#define DLEXT_MAXLEN 3
#define DLEXT ".so"
#define ENABLE_MULTIARCH 1
#define LIBDIR_BASENAME "lib64"
#define HAVE__SETJMP 1
#define RUBY_SETJMP(env) _setjmp((env))
#define RUBY_LONGJMP(env,val) _longjmp((env),val)
#define RUBY_JMP_BUF jmp_buf
#define USE_MJIT 1
#define USE_YJIT 0
#define RUBY_LIB_VERSION_BLANK 1
#define RUBY_PLATFORM "x86_64-linux"
#endif /* INCLUDE_RUBY_CONFIG_H */
include/ruby/vm.h 0000644 00000004126 15040330601 0007736 0 ustar 00 #ifndef RUBY_VM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_VM_H 1
/**
* @file
* @author $Author$
* @date Sat May 31 15:17:36 2008
* @copyright Copyright (C) 2008 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*
* We planned to have multiple VMs run side-by-side. The API here was a
* preparation of that feature. The topic branch was eventually abandoned, and
* we now have Ractor. This file is kind of obsolescent.
*/
#include "ruby/internal/dllexport.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* The opaque struct to hold VM internals. Its fields are intentionally hidden
* from extension libraries because it changes drastically time to time.
*/
typedef struct rb_vm_struct ruby_vm_t;
/**
* Destructs the passed VM. You don't have to call this API directly now,
* because there is no way to create one. There is only one VM at one time.
* ruby_stop() should just suffice.
*/
int ruby_vm_destruct(ruby_vm_t *vm);
/**
* ruby_vm_at_exit registers a function _func_ to be invoked when a VM
* passed away. Functions registered this way runs in reverse order
* of registration, just like END {} block does. The difference is
* its timing to be triggered. ruby_vm_at_exit functions runs when a
* VM _passed_ _away_, while END {} blocks runs just _before_ a VM
* _is_ _passing_ _away_.
*
* You cannot register a function to another VM than where you are in.
* So where to register is intuitive, omitted. OTOH the argument
* _func_ cannot know which VM it is in because at the time of
* invocation, the VM has already died and there is no execution
* context. The VM itself is passed as the first argument to it.
*
* @param[in] func the function to register.
*/
void ruby_vm_at_exit(void(*func)(ruby_vm_t *));
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_VM_H */
include/ruby/oniguruma.h 0000644 00000000406 15040330602 0011320 0 ustar 00 #ifndef ONIGURUMA_H
#define ONIGURUMA_H
#include "onigmo.h"
#define ONIGURUMA
#define ONIGURUMA_VERSION_MAJOR ONIGMO_VERSION_MAJOR
#define ONIGURUMA_VERSION_MINOR ONIGMO_VERSION_MINOR
#define ONIGURUMA_VERSION_TEENY ONIGMO_VERSION_TEENY
#endif /* ONIGURUMA_H */
include/ruby/onigmo.h 0000644 00000127465 15040330602 0010621 0 ustar 00 #ifndef ONIGMO_H
#define ONIGMO_H
/**********************************************************************
onigmo.h - Onigmo (Oniguruma-mod) (regular expression library)
**********************************************************************/
/*-
* Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* Copyright (c) 2011-2017 K.Takata <kentkt AT csc DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
# if 0
} /* satisfy cc-mode */
# endif
#endif
#define ONIGMO_VERSION_MAJOR 6
#define ONIGMO_VERSION_MINOR 1
#define ONIGMO_VERSION_TEENY 3
#ifndef ONIG_EXTERN
# ifdef RUBY_EXTERN
# define ONIG_EXTERN RUBY_EXTERN
# else
# if defined(_WIN32) && !defined(__GNUC__)
# if defined(EXPORT) || defined(RUBY_EXPORT)
# define ONIG_EXTERN extern __declspec(dllexport)
# else
# define ONIG_EXTERN extern __declspec(dllimport)
# endif
# endif
# endif
#endif
#ifndef ONIG_EXTERN
# define ONIG_EXTERN extern
#endif
#ifndef RUBY
# ifndef RUBY_SYMBOL_EXPORT_BEGIN
# define RUBY_SYMBOL_EXPORT_BEGIN
# define RUBY_SYMBOL_EXPORT_END
# endif
#endif
RUBY_SYMBOL_EXPORT_BEGIN
#include <stddef.h> /* for size_t */
/* PART: character encoding */
#ifndef ONIG_ESCAPE_UCHAR_COLLISION
# define UChar OnigUChar
#endif
typedef unsigned char OnigUChar;
typedef unsigned int OnigCodePoint;
typedef unsigned int OnigCtype;
typedef size_t OnigDistance;
typedef ptrdiff_t OnigPosition;
#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0)
/*
* Onig casefold/case mapping flags and related definitions
*
* Subfields (starting with 0 at LSB):
* 0-2: Code point count in casefold.h
* 3-12: Index into SpecialCaseMapping array in casefold.h
* 13-22: Case folding/mapping flags
*/
typedef unsigned int OnigCaseFoldType; /* case fold flag */
ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag;
/* bits for actual code point count; 3 bits is more than enough, currently only 2 used */
#define OnigCodePointMaskWidth 3
#define OnigCodePointMask ((1<<OnigCodePointMaskWidth)-1)
#define OnigCodePointCount(n) ((n)&OnigCodePointMask)
#define OnigCaseFoldFlags(n) ((n)&~OnigCodePointMask)
/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */ /* no longer usable with these values! */
/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */ /* no longer usable with these values! */
/* bits for index into table with separate titlecase mappings */
/* 10 bits provide 1024 values */
#define OnigSpecialIndexShift 3
#define OnigSpecialIndexWidth 10
#define ONIGENC_CASE_UPCASE (1<<13) /* has/needs uppercase mapping */
#define ONIGENC_CASE_DOWNCASE (1<<14) /* has/needs lowercase mapping */
#define ONIGENC_CASE_TITLECASE (1<<15) /* has/needs (special) titlecase mapping */
#define ONIGENC_CASE_SPECIAL_OFFSET 3 /* offset in bits from ONIGENC_CASE to ONIGENC_CASE_SPECIAL */
#define ONIGENC_CASE_UP_SPECIAL (1<<16) /* has special upcase mapping */
#define ONIGENC_CASE_DOWN_SPECIAL (1<<17) /* has special downcase mapping */
#define ONIGENC_CASE_MODIFIED (1<<18) /* data has been modified */
#define ONIGENC_CASE_FOLD (1<<19) /* has/needs case folding */
#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20) /* needs mapping specific to Turkic languages; better not change original value! */
#define ONIGENC_CASE_FOLD_LITHUANIAN (1<<21) /* needs Lithuanian-specific mapping */
#define ONIGENC_CASE_ASCII_ONLY (1<<22) /* only modify ASCII range */
#define ONIGENC_CASE_IS_TITLECASE (1<<23) /* character itself is already titlecase */
#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30) /* better not change original value! */
#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag
#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3
#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13
/* 13 => Unicode:0x1ffc */
/* code range */
#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0])
#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1]
#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2]
typedef struct {
int byte_len; /* argument(original) character(s) byte length */
int code_len; /* number of code */
OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN];
} OnigCaseFoldCodeItem;
typedef struct {
OnigCodePoint esc;
OnigCodePoint anychar;
OnigCodePoint anytime;
OnigCodePoint zero_or_one_time;
OnigCodePoint one_or_more_time;
OnigCodePoint anychar_anytime;
} OnigMetaCharTableType;
typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);
typedef struct OnigEncodingTypeST {
int (*precise_mbc_enc_len)(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
const char* name;
int max_enc_len;
int min_enc_len;
int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*code_to_mbclen)(OnigCodePoint code, const struct OnigEncodingTypeST* enc);
int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf, const struct OnigEncodingTypeST* enc);
int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, const struct OnigEncodingTypeST* enc);
int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, const struct OnigEncodingTypeST* enc);
int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[], const struct OnigEncodingTypeST* enc);
int (*property_name_to_ctype)(const struct OnigEncodingTypeST* enc, const OnigUChar* p, const OnigUChar* end);
int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype, const struct OnigEncodingTypeST* enc);
int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], const struct OnigEncodingTypeST* enc);
OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
int (*case_map)(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
int ruby_encoding_index;
unsigned int flags;
} OnigEncodingType;
typedef const OnigEncodingType* OnigEncoding;
ONIG_EXTERN const OnigEncodingType OnigEncodingASCII;
#ifndef RUBY
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_1;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_2;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_3;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_4;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_5;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_6;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_7;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_8;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_9;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_10;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_11;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_13;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_14;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_15;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_16;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_8;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16BE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16LE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32BE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32LE;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_JP;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_TW;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_KR;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_CN;
ONIG_EXTERN const OnigEncodingType OnigEncodingShift_JIS;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_31J;
/* ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8; */
ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_R;
ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_U;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1250;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1251;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1252;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1253;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1254;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1257;
ONIG_EXTERN const OnigEncodingType OnigEncodingBIG5;
ONIG_EXTERN const OnigEncodingType OnigEncodingGB18030;
#endif /* RUBY */
#define ONIG_ENCODING_ASCII (&OnigEncodingASCII)
#ifndef RUBY
# define ONIG_ENCODING_ISO_8859_1 (&OnigEncodingISO_8859_1)
# define ONIG_ENCODING_ISO_8859_2 (&OnigEncodingISO_8859_2)
# define ONIG_ENCODING_ISO_8859_3 (&OnigEncodingISO_8859_3)
# define ONIG_ENCODING_ISO_8859_4 (&OnigEncodingISO_8859_4)
# define ONIG_ENCODING_ISO_8859_5 (&OnigEncodingISO_8859_5)
# define ONIG_ENCODING_ISO_8859_6 (&OnigEncodingISO_8859_6)
# define ONIG_ENCODING_ISO_8859_7 (&OnigEncodingISO_8859_7)
# define ONIG_ENCODING_ISO_8859_8 (&OnigEncodingISO_8859_8)
# define ONIG_ENCODING_ISO_8859_9 (&OnigEncodingISO_8859_9)
# define ONIG_ENCODING_ISO_8859_10 (&OnigEncodingISO_8859_10)
# define ONIG_ENCODING_ISO_8859_11 (&OnigEncodingISO_8859_11)
# define ONIG_ENCODING_ISO_8859_13 (&OnigEncodingISO_8859_13)
# define ONIG_ENCODING_ISO_8859_14 (&OnigEncodingISO_8859_14)
# define ONIG_ENCODING_ISO_8859_15 (&OnigEncodingISO_8859_15)
# define ONIG_ENCODING_ISO_8859_16 (&OnigEncodingISO_8859_16)
# define ONIG_ENCODING_UTF_8 (&OnigEncodingUTF_8)
# define ONIG_ENCODING_UTF_16BE (&OnigEncodingUTF_16BE)
# define ONIG_ENCODING_UTF_16LE (&OnigEncodingUTF_16LE)
# define ONIG_ENCODING_UTF_32BE (&OnigEncodingUTF_32BE)
# define ONIG_ENCODING_UTF_32LE (&OnigEncodingUTF_32LE)
# define ONIG_ENCODING_EUC_JP (&OnigEncodingEUC_JP)
# define ONIG_ENCODING_EUC_TW (&OnigEncodingEUC_TW)
# define ONIG_ENCODING_EUC_KR (&OnigEncodingEUC_KR)
# define ONIG_ENCODING_EUC_CN (&OnigEncodingEUC_CN)
# define ONIG_ENCODING_SHIFT_JIS (&OnigEncodingShift_JIS)
# define ONIG_ENCODING_WINDOWS_31J (&OnigEncodingWindows_31J)
/* # define ONIG_ENCODING_KOI8 (&OnigEncodingKOI8) */
# define ONIG_ENCODING_KOI8_R (&OnigEncodingKOI8_R)
# define ONIG_ENCODING_KOI8_U (&OnigEncodingKOI8_U)
# define ONIG_ENCODING_WINDOWS_1250 (&OnigEncodingWindows_1250)
# define ONIG_ENCODING_WINDOWS_1251 (&OnigEncodingWindows_1251)
# define ONIG_ENCODING_WINDOWS_1252 (&OnigEncodingWindows_1252)
# define ONIG_ENCODING_WINDOWS_1253 (&OnigEncodingWindows_1253)
# define ONIG_ENCODING_WINDOWS_1254 (&OnigEncodingWindows_1254)
# define ONIG_ENCODING_WINDOWS_1257 (&OnigEncodingWindows_1257)
# define ONIG_ENCODING_BIG5 (&OnigEncodingBIG5)
# define ONIG_ENCODING_GB18030 (&OnigEncodingGB18030)
/* old names */
# define ONIG_ENCODING_SJIS ONIG_ENCODING_SHIFT_JIS
# define ONIG_ENCODING_CP932 ONIG_ENCODING_WINDOWS_31J
# define ONIG_ENCODING_CP1250 ONIG_ENCODING_WINDOWS_1250
# define ONIG_ENCODING_CP1251 ONIG_ENCODING_WINDOWS_1251
# define ONIG_ENCODING_CP1252 ONIG_ENCODING_WINDOWS_1252
# define ONIG_ENCODING_CP1253 ONIG_ENCODING_WINDOWS_1253
# define ONIG_ENCODING_CP1254 ONIG_ENCODING_WINDOWS_1254
# define ONIG_ENCODING_CP1257 ONIG_ENCODING_WINDOWS_1257
# define ONIG_ENCODING_UTF8 ONIG_ENCODING_UTF_8
# define ONIG_ENCODING_UTF16_BE ONIG_ENCODING_UTF_16BE
# define ONIG_ENCODING_UTF16_LE ONIG_ENCODING_UTF_16LE
# define ONIG_ENCODING_UTF32_BE ONIG_ENCODING_UTF_32BE
# define ONIG_ENCODING_UTF32_LE ONIG_ENCODING_UTF_32LE
#endif /* RUBY */
#define ONIG_ENCODING_UNDEF ((OnigEncoding )0)
/* this declaration needs to be here because it is used in string.c in Ruby */
ONIG_EXTERN
int onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
/* work size */
#define ONIGENC_CODE_TO_MBC_MAXLEN 7
#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18
/* 18: 6(max-byte) * 3(case-fold chars) */
/* character types */
#define ONIGENC_CTYPE_NEWLINE 0
#define ONIGENC_CTYPE_ALPHA 1
#define ONIGENC_CTYPE_BLANK 2
#define ONIGENC_CTYPE_CNTRL 3
#define ONIGENC_CTYPE_DIGIT 4
#define ONIGENC_CTYPE_GRAPH 5
#define ONIGENC_CTYPE_LOWER 6
#define ONIGENC_CTYPE_PRINT 7
#define ONIGENC_CTYPE_PUNCT 8
#define ONIGENC_CTYPE_SPACE 9
#define ONIGENC_CTYPE_UPPER 10
#define ONIGENC_CTYPE_XDIGIT 11
#define ONIGENC_CTYPE_WORD 12
#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */
#define ONIGENC_CTYPE_ASCII 14
#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII
/* flags */
#define ONIGENC_FLAG_NONE 0U
#define ONIGENC_FLAG_UNICODE 1U
#define onig_enc_len(enc,p,e) ONIGENC_MBC_ENC_LEN(enc, p, e)
#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF)
#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1)
#define ONIGENC_IS_MBC_HEAD(enc,p,e) (ONIGENC_MBC_ENC_LEN(enc,p,e) != 1)
#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128)
#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128)
#define ONIGENC_IS_MBC_WORD(enc,s,end) \
ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
#define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) \
onigenc_ascii_is_code_ctype( \
ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc)
#define ONIGENC_IS_UNICODE(enc) ((enc)->flags & ONIGENC_FLAG_UNICODE)
#define ONIGENC_NAME(enc) ((enc)->name)
#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \
(enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf,enc)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
(enc)->is_allowed_reverse_match(s,end,enc)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s,end) \
(enc)->left_adjust_char_head(start, s, end, enc)
#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \
(enc)->apply_all_case_fold(case_fold_flag,f,arg,enc)
#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \
(enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs,enc)
#define ONIGENC_STEP_BACK(enc,start,s,end,n) \
onigenc_step_back((enc),(start),(s),(end),(n))
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n) (n)
#define ONIGENC_MBCLEN_CHARFOUND_P(r) (0 < (r))
#define ONIGENC_MBCLEN_CHARFOUND_LEN(r) (r)
#define ONIGENC_CONSTRUCT_MBCLEN_INVALID() (-1)
#define ONIGENC_MBCLEN_INVALID_P(r) ((r) == -1)
#define ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n) (-1-(n))
#define ONIGENC_MBCLEN_NEEDMORE_P(r) ((r) < -1)
#define ONIGENC_MBCLEN_NEEDMORE_LEN(r) (-1-(r))
#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e) (enc)->precise_mbc_enc_len(p,e,enc)
ONIG_EXTERN
int onigenc_mbclen(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
#define ONIGENC_MBC_ENC_LEN(enc,p,e) onigenc_mbclen(p,e,enc)
#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len)
#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc)
#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len)
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end),enc)
#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end),enc)
#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code,enc)
#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf,enc)
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
(enc)->property_name_to_ctype(enc,p,end)
#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype,enc)
#define ONIGENC_IS_CODE_NEWLINE(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
#define ONIGENC_IS_CODE_GRAPH(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
#define ONIGENC_IS_CODE_PRINT(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
#define ONIGENC_IS_CODE_ALNUM(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
#define ONIGENC_IS_CODE_ALPHA(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
#define ONIGENC_IS_CODE_LOWER(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
#define ONIGENC_IS_CODE_UPPER(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
#define ONIGENC_IS_CODE_CNTRL(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
#define ONIGENC_IS_CODE_PUNCT(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
#define ONIGENC_IS_CODE_SPACE(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
#define ONIGENC_IS_CODE_BLANK(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
#define ONIGENC_IS_CODE_DIGIT(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
#define ONIGENC_IS_CODE_XDIGIT(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
#define ONIGENC_IS_CODE_WORD(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)
#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \
(enc)->get_ctype_code_range(ctype,sbout,ranges,enc)
ONIG_EXTERN
OnigUChar* onigenc_step_back(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, int n);
/* encoding API */
ONIG_EXTERN
int onigenc_init(void);
ONIG_EXTERN
int onigenc_set_default_encoding(OnigEncoding enc);
ONIG_EXTERN
OnigEncoding onigenc_get_default_encoding(void);
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, const OnigUChar** prev);
ONIG_EXTERN
OnigUChar* onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
OnigUChar* onigenc_get_left_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
int onigenc_strlen(OnigEncoding enc, const OnigUChar* p, const OnigUChar* end);
ONIG_EXTERN
int onigenc_strlen_null(OnigEncoding enc, const OnigUChar* p);
ONIG_EXTERN
int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);
/* PART: regular expression */
/* config parameters */
#define ONIG_NREGION 4
#define ONIG_MAX_CAPTURE_GROUP_NUM 32767
#define ONIG_MAX_BACKREF_NUM 1000
#define ONIG_MAX_REPEAT_NUM 100000
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000
/* constants */
#define ONIG_MAX_ERROR_MESSAGE_LEN 90
typedef unsigned int OnigOptionType;
#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE
/* options */
#define ONIG_OPTION_NONE 0U
#define ONIG_OPTION_IGNORECASE 1U
#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1)
#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1)
#define ONIG_OPTION_DOTALL ONIG_OPTION_MULTILINE
#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1)
#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1)
#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1)
#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1)
#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1)
#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
/* options (search time) */
#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1)
#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1)
#define ONIG_OPTION_NOTBOS (ONIG_OPTION_NOTEOL << 1)
#define ONIG_OPTION_NOTEOS (ONIG_OPTION_NOTBOS << 1)
/* options (ctype range) */
#define ONIG_OPTION_ASCII_RANGE (ONIG_OPTION_NOTEOS << 1)
#define ONIG_OPTION_POSIX_BRACKET_ALL_RANGE (ONIG_OPTION_ASCII_RANGE << 1)
#define ONIG_OPTION_WORD_BOUND_ALL_RANGE (ONIG_OPTION_POSIX_BRACKET_ALL_RANGE << 1)
/* options (newline) */
#define ONIG_OPTION_NEWLINE_CRLF (ONIG_OPTION_WORD_BOUND_ALL_RANGE << 1)
#define ONIG_OPTION_MAXBIT ONIG_OPTION_NEWLINE_CRLF /* limit */
#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt))
#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt))
#define ONIG_IS_OPTION_ON(options,option) ((options) & (option))
/* syntax */
typedef struct {
unsigned int op;
unsigned int op2;
unsigned int behavior;
OnigOptionType options; /* default option */
OnigMetaCharTableType meta_char_table;
} OnigSyntaxType;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxASIS;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixBasic;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixExtended;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxEmacs;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGrep;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGnuRegex;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxJava;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58_NG;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxRuby;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPython;
/* predefined syntaxes (see regsyntax.c) */
#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS)
#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic)
#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended)
#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs)
#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep)
#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex)
#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava)
#define ONIG_SYNTAX_PERL58 (&OnigSyntaxPerl58)
#define ONIG_SYNTAX_PERL58_NG (&OnigSyntaxPerl58_NG)
#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl)
#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby)
#define ONIG_SYNTAX_PYTHON (&OnigSyntaxPython)
/* default syntax */
ONIG_EXTERN const OnigSyntaxType* OnigDefaultSyntax;
#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax
/* syntax (operators) */
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0)
#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1) /* . */
#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2) /* * */
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3)
#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4) /* + */
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5)
#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6) /* ? */
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7)
#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8) /* {lower,upper} */
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9) /* \{lower,upper\} */
#define ONIG_SYN_OP_VBAR_ALT (1U<<10) /* | */
#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11) /* \| */
#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12) /* (...) */
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13) /* \(...\) */
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14) /* \A, \Z, \z */
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15) /* \G */
#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16) /* \num */
#define ONIG_SYN_OP_BRACKET_CC (1U<<17) /* [...] */
#define ONIG_SYN_OP_ESC_W_WORD (1U<<18) /* \w, \W */
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19) /* \<. \> */
#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20) /* \b, \B */
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21) /* \s, \S */
#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22) /* \d, \D */
#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23) /* ^, $ */
#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24) /* [:xxxx:] */
#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25) /* ??,*?,+?,{n,m}? */
#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26) /* \n,\r,\t,\a ... */
#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27) /* \cx */
#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28) /* \OOO */
#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29) /* \xHH */
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30) /* \x{7HHHHHHH} */
#define ONIG_SYN_OP_ESC_O_BRACE_OCTAL (1U<<31) /* \o{OOO} */
#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0) /* \Q...\E */
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1) /* (?...) */
#define ONIG_SYN_OP2_OPTION_PERL (1U<<2) /* (?imsxadlu), (?-imsx), (?^imsxalu) */
#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3) /* (?imxadu), (?-imx) */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4) /* ?+,*+,++ */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5) /* {n,m}+ */
#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6) /* [...&&..[..]..] */
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7) /* (?<name>...) */
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8) /* \k<name> */
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9) /* \g<name>, \g<n> */
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10) /* (?@..),(?@<x>..) */
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11) /* \C-x */
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12) /* \M-x */
#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13) /* \v as VTAB */
#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14) /* \uHHHH */
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */
#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */
#define ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK (1U<<21) /* \R as (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) */
#define ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER (1U<<22) /* \X */
#define ONIG_SYN_OP2_ESC_V_VERTICAL_WHITESPACE (1U<<23) /* \v, \V -- Perl */ /* NOTIMPL */
#define ONIG_SYN_OP2_ESC_H_HORIZONTAL_WHITESPACE (1U<<24) /* \h, \H -- Perl */ /* NOTIMPL */
#define ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP (1U<<25) /* \K */
#define ONIG_SYN_OP2_ESC_G_BRACE_BACKREF (1U<<26) /* \g{name}, \g{n} */
#define ONIG_SYN_OP2_QMARK_SUBEXP_CALL (1U<<27) /* (?&name), (?n), (?R), (?0) */
#define ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET (1U<<28) /* (?|...) */ /* NOTIMPL */
#define ONIG_SYN_OP2_QMARK_LPAREN_CONDITION (1U<<29) /* (?(cond)yes...|no...) */
#define ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP (1U<<30) /* (?P<name>...), (?P=name), (?P>name) -- Python/PCRE */
#define ONIG_SYN_OP2_QMARK_TILDE_ABSENT (1U<<31) /* (?~...) */
/* #define ONIG_SYN_OP2_OPTION_JAVA (1U<<xx) */ /* (?idmsux), (?-idmsux) */ /* NOTIMPL */
/* syntax (behavior) */
#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31) /* not implemented */
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0) /* ?, *, +, {n,m} */
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1) /* error or ignore */
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2) /* ...)... */
#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3) /* {??? */
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4) /* {,n} => {0,n} */
#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5) /* /(\1)/,/\1()/ ..*/
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6) /* (?<=a|bc) */
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7) /* see doc/RE */
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8) /* (?<x>)(?<x>) */
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9) /* a{n}?=(?:a{n})? */
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL (1U<<10) /* (?<x>)(?<x>)(?&x) */
#define ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP (1U<<11) /* (?<x>)(?<x>)\k<x> */
/* syntax (behavior) in char class [...] */
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20) /* [^...] */
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21) /* [..\w..] etc.. */
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22)
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23) /* [0-9-a]=[0-9\-a] */
/* syntax (behavior) warning */
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24) /* [,-,] */
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25) /* (?:a*)+ */
#define ONIG_SYN_WARN_CC_DUP (1U<<26) /* [aa] */
/* meta character specifiers (onig_set_meta_char()) */
#define ONIG_META_CHAR_ESCAPE 0
#define ONIG_META_CHAR_ANYCHAR 1
#define ONIG_META_CHAR_ANYTIME 2
#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3
#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4
#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5
#define ONIG_INEFFECTIVE_META_CHAR 0
/* error codes */
#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000)
/* normal return */
#define ONIG_NORMAL 0
#define ONIG_MISMATCH -1
#define ONIG_NO_SUPPORT_CONFIG -2
/* internal error */
#define ONIGERR_MEMORY -5
#define ONIGERR_TYPE_BUG -6
#define ONIGERR_PARSER_BUG -11
#define ONIGERR_STACK_BUG -12
#define ONIGERR_UNDEFINED_BYTECODE -13
#define ONIGERR_UNEXPECTED_BYTECODE -14
#define ONIGERR_MATCH_STACK_LIMIT_OVER -15
#define ONIGERR_PARSE_DEPTH_LIMIT_OVER -16
#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SET -21
#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22
/* general error */
#define ONIGERR_INVALID_ARGUMENT -30
/* syntax error */
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100
#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101
#define ONIGERR_EMPTY_CHAR_CLASS -102
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103
#define ONIGERR_END_PATTERN_AT_ESCAPE -104
#define ONIGERR_END_PATTERN_AT_META -105
#define ONIGERR_END_PATTERN_AT_CONTROL -106
#define ONIGERR_META_CODE_SYNTAX -108
#define ONIGERR_CONTROL_CODE_SYNTAX -109
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110
#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114
#define ONIGERR_NESTED_REPEAT_OPERATOR -115
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117
#define ONIGERR_END_PATTERN_IN_GROUP -118
#define ONIGERR_UNDEFINED_GROUP_OPTION -119
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121
#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123
#define ONIGERR_INVALID_CONDITION_PATTERN -124
/* values error (syntax error) */
#define ONIGERR_TOO_BIG_NUMBER -200
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206
#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207
#define ONIGERR_INVALID_BACKREF -208
#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209
#define ONIGERR_TOO_MANY_CAPTURE_GROUPS -210
#define ONIGERR_TOO_SHORT_DIGITS -211
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212
#define ONIGERR_EMPTY_GROUP_NAME -214
#define ONIGERR_INVALID_GROUP_NAME -215
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216
#define ONIGERR_UNDEFINED_NAME_REFERENCE -217
#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218
#define ONIGERR_MULTIPLEX_DEFINED_NAME -219
#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220
#define ONIGERR_NEVER_ENDING_RECURSION -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223
#define ONIGERR_INVALID_CODE_POINT_VALUE -400
#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402
#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403
/* errors related to thread */
/* #define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT -1001 */
/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */
#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])
#ifdef USE_CAPTURE_HISTORY
typedef struct OnigCaptureTreeNodeStruct {
int group; /* group number */
OnigPosition beg;
OnigPosition end;
int allocated;
int num_childs;
struct OnigCaptureTreeNodeStruct** childs;
} OnigCaptureTreeNode;
#endif
/* match result region type */
struct re_registers {
int allocated;
int num_regs;
OnigPosition* beg;
OnigPosition* end;
#ifdef USE_CAPTURE_HISTORY
/* extended */
OnigCaptureTreeNode* history_root; /* capture history tree root */
#endif
};
/* capture tree traverse */
#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1
#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2
#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \
( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )
#define ONIG_REGION_NOTPOS -1
typedef struct re_registers OnigRegion;
typedef struct {
OnigEncoding enc;
OnigUChar* par;
OnigUChar* par_end;
} OnigErrorInfo;
typedef struct {
int lower;
int upper;
long base_num;
long inner_num;
} OnigRepeatRange;
typedef void (*OnigWarnFunc)(const char* s);
extern void onig_null_warn(const char* s);
#define ONIG_NULL_WARN onig_null_warn
#define ONIG_CHAR_TABLE_SIZE 256
typedef struct re_pattern_buffer {
/* common members of BBuf(bytes-buffer) */
unsigned char* p; /* compiled pattern */
unsigned int used; /* used space for p */
unsigned int alloc; /* allocated space for p */
int num_mem; /* used memory(...) num counted from 1 */
int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
int num_null_check; /* OP_NULL_CHECK_START/END id counter */
int num_comb_exp_check; /* combination explosion check */
int num_call; /* number of subexp call */
unsigned int capture_history; /* (?@...) flag (1-31) */
unsigned int bt_mem_start; /* need backtrack flag */
unsigned int bt_mem_end; /* need backtrack flag */
int stack_pop_level;
int repeat_range_alloc;
OnigOptionType options;
OnigRepeatRange* repeat_range;
OnigEncoding enc;
const OnigSyntaxType* syntax;
void* name_table;
OnigCaseFoldType case_fold_flag;
/* optimization info (string search, char-map and anchors) */
int optimize; /* optimize flag */
int threshold_len; /* search str-length for apply optimize */
int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
OnigDistance anchor_dmin; /* (SEMI_)END_BUF anchor distance */
OnigDistance anchor_dmax; /* (SEMI_)END_BUF anchor distance */
int sub_anchor; /* start-anchor for exact or map */
unsigned char *exact;
unsigned char *exact_end;
unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
int *int_map; /* BM skip for exact_len > 255 */
int *int_map_backward; /* BM skip for backward search */
OnigDistance dmin; /* min-distance of exact or map */
OnigDistance dmax; /* max-distance of exact or map */
/* rb_hrtime_t from hrtime.h */
#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
int128_t timelimit;
#else
uint64_t timelimit;
#endif
/* regex_t link chain */
struct re_pattern_buffer* chain; /* escape compile-conflict */
} OnigRegexType;
typedef OnigRegexType* OnigRegex;
#ifndef ONIG_ESCAPE_REGEX_T_COLLISION
typedef OnigRegexType regex_t;
#endif
typedef struct {
int num_of_elements;
OnigEncoding pattern_enc;
OnigEncoding target_enc;
const OnigSyntaxType* syntax;
OnigOptionType option;
OnigCaseFoldType case_fold_flag;
} OnigCompileInfo;
/* Oniguruma Native API */
ONIG_EXTERN
int onig_initialize(OnigEncoding encodings[], int n);
ONIG_EXTERN
int onig_init(void);
ONIG_EXTERN
int onig_error_code_to_str(OnigUChar* s, OnigPosition err_code, ...);
ONIG_EXTERN
void onig_set_warn_func(OnigWarnFunc f);
ONIG_EXTERN
void onig_set_verb_warn_func(OnigWarnFunc f);
ONIG_EXTERN
int onig_new(OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
ONIG_EXTERN
int onig_reg_init(OnigRegex reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, const OnigSyntaxType* syntax);
ONIG_EXTERN
int onig_new_without_alloc(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
ONIG_EXTERN
int onig_new_deluxe(OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
ONIG_EXTERN
void onig_free(OnigRegex);
ONIG_EXTERN
void onig_free_body(OnigRegex);
ONIG_EXTERN
OnigPosition onig_scan(OnigRegex reg, const OnigUChar* str, const OnigUChar* end, OnigRegion* region, OnigOptionType option, int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*), void* callback_arg);
ONIG_EXTERN
OnigPosition onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
OnigPosition onig_search_gpos(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* global_pos, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
OnigPosition onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
int onig_check_linear_time(OnigRegex reg);
ONIG_EXTERN
OnigRegion* onig_region_new(void);
ONIG_EXTERN
void onig_region_init(OnigRegion* region);
ONIG_EXTERN
void onig_region_free(OnigRegion* region, int free_self);
ONIG_EXTERN
void onig_region_copy(OnigRegion* to, const OnigRegion* from);
ONIG_EXTERN
void onig_region_clear(OnigRegion* region);
ONIG_EXTERN
int onig_region_resize(OnigRegion* region, int n);
ONIG_EXTERN
int onig_region_set(OnigRegion* region, int at, int beg, int end);
ONIG_EXTERN
int onig_name_to_group_numbers(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums);
ONIG_EXTERN
int onig_name_to_backref_number(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, const OnigRegion *region);
ONIG_EXTERN
int onig_foreach_name(OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg);
ONIG_EXTERN
int onig_number_of_names(const OnigRegexType *reg);
ONIG_EXTERN
int onig_number_of_captures(const OnigRegexType *reg);
ONIG_EXTERN
int onig_number_of_capture_histories(const OnigRegexType *reg);
#ifdef USE_CAPTURE_HISTORY
ONIG_EXTERN
OnigCaptureTreeNode* onig_get_capture_tree(OnigRegion* region);
#endif
ONIG_EXTERN
int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*), void* arg);
ONIG_EXTERN
int onig_noname_group_capture_is_active(const OnigRegexType *reg);
ONIG_EXTERN
OnigEncoding onig_get_encoding(const OnigRegexType *reg);
ONIG_EXTERN
OnigOptionType onig_get_options(const OnigRegexType *reg);
ONIG_EXTERN
OnigCaseFoldType onig_get_case_fold_flag(const OnigRegexType *reg);
ONIG_EXTERN
const OnigSyntaxType* onig_get_syntax(const OnigRegexType *reg);
ONIG_EXTERN
int onig_set_default_syntax(const OnigSyntaxType* syntax);
ONIG_EXTERN
void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
ONIG_EXTERN
unsigned int onig_get_syntax_op(const OnigSyntaxType* syntax);
ONIG_EXTERN
unsigned int onig_get_syntax_op2(const OnigSyntaxType* syntax);
ONIG_EXTERN
unsigned int onig_get_syntax_behavior(const OnigSyntaxType* syntax);
ONIG_EXTERN
OnigOptionType onig_get_syntax_options(const OnigSyntaxType* syntax);
ONIG_EXTERN
void onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op);
ONIG_EXTERN
void onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2);
ONIG_EXTERN
void onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior);
ONIG_EXTERN
void onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options);
ONIG_EXTERN
int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code);
ONIG_EXTERN
void onig_copy_encoding(OnigEncodingType *to, OnigEncoding from);
ONIG_EXTERN
OnigCaseFoldType onig_get_default_case_fold_flag(void);
ONIG_EXTERN
int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag);
ONIG_EXTERN
unsigned int onig_get_match_stack_limit_size(void);
ONIG_EXTERN
int onig_set_match_stack_limit_size(unsigned int size);
ONIG_EXTERN
unsigned int onig_get_parse_depth_limit(void);
ONIG_EXTERN
int onig_set_parse_depth_limit(unsigned int depth);
ONIG_EXTERN
int onig_end(void);
ONIG_EXTERN
const char* onig_version(void);
ONIG_EXTERN
const char* onig_copyright(void);
RUBY_SYMBOL_EXPORT_END
#ifdef __cplusplus
# if 0
{ /* satisfy cc-mode */
# endif
}
#endif
#endif /* ONIGMO_H */
include/ruby/backward.h 0000644 00000002166 15040330602 0011075 0 ustar 00 #ifndef RUBY_RUBY_BACKWARD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_BACKWARD_H 1
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/value.h"
#include "ruby/internal/interpreter.h"
#include "ruby/backward/2/attributes.h"
#define RBIMPL_ATTR_DEPRECATED_SINCE(ver) RBIMPL_ATTR_DEPRECATED(("since " #ver))
#define RBIMPL_ATTR_DEPRECATED_INTERNAL(ver) RBIMPL_ATTR_DEPRECATED(("since "#ver", also internal"))
#define RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() RBIMPL_ATTR_DEPRECATED(("only for internal use"))
RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() void rb_clear_constant_cache(void);
/* from version.c */
#if defined(RUBY_SHOW_COPYRIGHT_TO_DIE) && !!(RUBY_SHOW_COPYRIGHT_TO_DIE+0)
# error RUBY_SHOW_COPYRIGHT_TO_DIE is deprecated
#endif
#endif /* RUBY_RUBY_BACKWARD_H */
include/ruby/backward/2/stdarg.h 0000644 00000004606 15040330602 0012523 0 ustar 00 #ifndef RUBY_BACKWARD2_STDARG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_STDARG_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines old #_
*
* Nobody should ever use these macros any longer. No known compilers lack
* prototypes today. It's 21st century. Just forget them.
*/
#undef _
/**
* @deprecated Nobody practically needs this macro any longer.
* @brief This was a transition path from K&R to ANSI.
*/
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif
#undef __
/**
* @deprecated Nobody practically needs this macro any longer.
* @brief This was a transition path from K&R to ANSI.
*/
#ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args
#else
# define __(args) ()
#endif
/**
* Functions declared using this macro take arbitrary arguments, including
* void.
*
* ```CXX
* void func(ANYARGS);
* ```
*
* This was a necessary evil when there was no such thing like function
* overloading. But it is the 21st century today. People generally need not
* use this. Just use a granular typed function.
*
* @see ruby::backward::cxxanyargs
*/
#ifdef __cplusplus
#define ANYARGS ...
#else
#define ANYARGS
#endif
#endif /* RUBY_BACKWARD2_STDARG_H */
include/ruby/backward/2/inttypes.h 0000644 00000010046 15040330602 0013111 0 ustar 00 #ifndef RUBY_BACKWARD2_INTTYPES_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_INTTYPES_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief C99 shim for `<inttypes.h>`
*/
#include "ruby/internal/config.h" /* PRI_LL_PREFIX etc. are here */
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include "ruby/internal/value.h" /* PRI_VALUE_PREFIX is here. */
#ifndef PRI_INT_PREFIX
# define PRI_INT_PREFIX ""
#endif
#ifndef PRI_LONG_PREFIX
# define PRI_LONG_PREFIX "l"
#endif
#ifndef PRI_SHORT_PREFIX
# define PRI_SHORT_PREFIX "h"
#endif
#ifdef PRI_64_PREFIX
# /* Take that. */
#elif SIZEOF_LONG == 8
# define PRI_64_PREFIX PRI_LONG_PREFIX
#elif SIZEOF_LONG_LONG == 8
# define PRI_64_PREFIX PRI_LL_PREFIX
#endif
#ifndef PRIdPTR
# define PRIdPTR PRI_PTR_PREFIX"d"
# define PRIiPTR PRI_PTR_PREFIX"i"
# define PRIoPTR PRI_PTR_PREFIX"o"
# define PRIuPTR PRI_PTR_PREFIX"u"
# define PRIxPTR PRI_PTR_PREFIX"x"
# define PRIXPTR PRI_PTR_PREFIX"X"
#endif
#ifndef RUBY_PRI_VALUE_MARK
# define RUBY_PRI_VALUE_MARK "\v"
#endif
#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
# define PRIdVALUE PRIdPTR
# define PRIoVALUE PRIoPTR
# define PRIuVALUE PRIuPTR
# define PRIxVALUE PRIxPTR
# define PRIXVALUE PRIXPTR
# define PRIsVALUE PRIiPTR"" RUBY_PRI_VALUE_MARK
#else
# define PRIdVALUE PRI_VALUE_PREFIX"d"
# define PRIoVALUE PRI_VALUE_PREFIX"o"
# define PRIuVALUE PRI_VALUE_PREFIX"u"
# define PRIxVALUE PRI_VALUE_PREFIX"x"
# define PRIXVALUE PRI_VALUE_PREFIX"X"
# define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK
#endif
#ifndef PRI_VALUE_PREFIX
# define PRI_VALUE_PREFIX ""
#endif
#ifdef PRI_TIMET_PREFIX
# /* Take that. */
#elif SIZEOF_TIME_T == SIZEOF_INT
# define PRI_TIMET_PREFIX
#elif SIZEOF_TIME_T == SIZEOF_LONG
# define PRI_TIMET_PREFIX "l"
#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
# define PRI_TIMET_PREFIX PRI_LL_PREFIX
#endif
#ifdef PRI_PTRDIFF_PREFIX
# /* Take that. */
#elif SIZEOF_PTRDIFF_T == SIZEOF_INT
# define PRI_PTRDIFF_PREFIX ""
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
# define PRI_PTRDIFF_PREFIX "l"
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
# define PRI_PTRDIFF_PREFIX PRI_LL_PREFIX
#endif
#ifndef PRIdPTRDIFF
# define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
# define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
# define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
# define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
# define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
# define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
#endif
#ifdef PRI_SIZE_PREFIX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define PRI_SIZE_PREFIX ""
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define PRI_SIZE_PREFIX "l"
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define PRI_SIZE_PREFIX PRI_LL_PREFIX
#endif
#ifndef PRIdSIZE
# define PRIdSIZE PRI_SIZE_PREFIX"d"
# define PRIiSIZE PRI_SIZE_PREFIX"i"
# define PRIoSIZE PRI_SIZE_PREFIX"o"
# define PRIuSIZE PRI_SIZE_PREFIX"u"
# define PRIxSIZE PRI_SIZE_PREFIX"x"
# define PRIXSIZE PRI_SIZE_PREFIX"X"
#endif
#endif /* RUBY_BACKWARD2_INTTYPES_H */
include/ruby/backward/2/r_cast.h 0000644 00000003170 15040330602 0012505 0 ustar 00 #ifndef RUBY_BACKWARD2_R_CAST_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_R_CAST_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines old R_CAST
*
* Nobody is actively using this macro.
*/
#define R_CAST(st) (struct st*)
#define RMOVED(obj) (R_CAST(RMoved)(obj))
#if defined(__GNUC__)
# warning R_CAST and RMOVED are deprecated
#elif defined(_MSC_VER)
# pragma message("warning: R_CAST and RMOVED are deprecated")
#endif
#endif /* RUBY_BACKWARD2_R_CAST_H */
include/ruby/backward/2/stdalign.h 0000644 00000003127 15040330602 0013041 0 ustar 00 #ifndef RUBY_BACKWARD2_STDALIGN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_STDALIGN_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RUBY_ALIGNAS / #RUBY_ALIGNOF
*/
#include "ruby/internal/stdalign.h"
#undef RUBY_ALIGNAS
#undef RUBY_ALIGNOF
#define RUBY_ALIGNAS RBIMPL_ALIGNAS /**< @copydoc RBIMPL_ALIGNAS */
#define RUBY_ALIGNOF RBIMPL_ALIGNOF /**< @copydoc RBIMPL_ALIGNOF */
#endif /* RUBY_BACKWARD2_STDALIGN_H */
include/ruby/backward/2/gcc_version_since.h 0000644 00000003555 15040330602 0014723 0 ustar 00 #ifndef RUBY_BACKWARD2_GCC_VERSION_SINCE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_GCC_VERSION_SINCE_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines old GCC_VERSION_SINCE
*/
#include "ruby/internal/compiler_since.h"
#ifndef GCC_VERSION_SINCE
#define GCC_VERSION_SINCE(x, y, z) RBIMPL_COMPILER_SINCE(GCC, (x), (y), (z))
#endif
#ifndef GCC_VERSION_BEFORE
#define GCC_VERSION_BEFORE(x, y, z) \
(RBIMPL_COMPILER_BEFORE(GCC, (x), (y), (z)) || \
(RBIMPL_COMPILER_IS(GCC) && \
((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
(RBIMPL_COMPILER_VERSION_PATCH == (z))))))
#endif
#endif /* RUBY_BACKWARD2_GCC_VERSION_SINCE_H */
include/ruby/backward/2/limits.h 0000644 00000005763 15040330602 0012545 0 ustar 00 #ifndef RUBY_BACKWARD2_LIMITS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_LIMITS_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Historical shim for `<limits.h>`.
*
* The macros in this header file are obsolescent. Does anyone really need our
* own definition of `CHAR_BIT` today?
*/
#include "ruby/internal/config.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include "ruby/backward/2/long_long.h"
#ifndef LONG_MAX
# /* assuming 32bit(2's complement) long */
# define LONG_MAX 2147483647L
#endif
#ifndef LONG_MIN
# define LONG_MIN (-LONG_MAX-1)
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
#ifdef LLONG_MAX
# /* Take that. */
#elif defined(LONG_LONG_MAX)
# define LLONG_MAX LONG_LONG_MAX
#elif defined(_I64_MAX)
# define LLONG_MAX _I64_MAX
#else
# /* assuming 64bit(2's complement) long long */
# define LLONG_MAX 9223372036854775807LL
#endif
#ifdef LLONG_MIN
# /* Take that. */
#elif defined(LONG_LONG_MIN)
# define LLONG_MIN LONG_LONG_MIN
#elif defined(_I64_MAX)
# define LLONG_MIN _I64_MIN
#else
# define LLONG_MIN (-LLONG_MAX-1)
#endif
#ifdef SIZE_MAX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define SIZE_MAX ULLONG_MAX
# define SIZE_MIN ULLONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define SIZE_MAX ULONG_MAX
# define SIZE_MIN ULONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define SIZE_MAX UINT_MAX
# define SIZE_MIN UINT_MIN
#else
# define SIZE_MAX USHRT_MAX
# define SIZE_MIN USHRT_MIN
#endif
#ifdef SSIZE_MAX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define SSIZE_MAX LLONG_MAX
# define SSIZE_MIN LLONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define SSIZE_MAX LONG_MAX
# define SSIZE_MIN LONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define SSIZE_MAX INT_MAX
# define SSIZE_MIN INT_MIN
#else
# define SSIZE_MAX SHRT_MAX
# define SSIZE_MIN SHRT_MIN
#endif
#endif /* RUBY_BACKWARD2_LIMITS_H */
include/ruby/backward/2/rmodule.h 0000644 00000003631 15040330602 0012703 0 ustar 00 #ifndef RUBY_BACKWARD2_RMODULE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_RMODULE_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Orphan macros.
*
* These macros seems broken since at least 2011. Nobody (except ruby itself
* who is implementing the internals) could have used those macros for a while.
* Kept public as-is here to keep some theoretical backwards compatibility.
*/
#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
#define RMODULE_SUPER(m) RCLASS_SUPER(m)
#if defined(__GNUC__)
# warning RMODULE_* macros are deprecated
#elif defined(_MSC_VER)
# pragma message("warning: RMODULE_* macros are deprecated")
#endif
#endif /* RUBY_BACKWARD2_RMODULE_H */
include/ruby/backward/2/assume.h 0000644 00000005005 15040330602 0012526 0 ustar 00 #ifndef RUBY_BACKWARD2_ASSUME_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_ASSUME_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #ASSUME / #RB_LIKELY / #UNREACHABLE
*/
#include "ruby/internal/config.h"
#include "ruby/internal/assume.h"
#include "ruby/internal/has/builtin.h"
#define ASSUME RBIMPL_ASSUME /**< @old{RBIMPL_ASSUME} */
#define UNREACHABLE RBIMPL_UNREACHABLE() /**< @old{RBIMPL_UNREACHABLE} */
#define UNREACHABLE_RETURN RBIMPL_UNREACHABLE_RETURN /**< @old{RBIMPL_UNREACHABLE_RETURN} */
/* likely */
#if RBIMPL_HAS_BUILTIN(__builtin_expect)
/**
* Asserts that the given Boolean expression likely holds.
*
* @param x An expression that likely holds.
*
* @note Consider this macro carefully. It has been here since when CPUs were
* like babies, but contemporary processors are beasts. They are
* smarter than mare mortals like us today. Their branch predictions
* highly expectedly outperform your use of this macro.
*/
# define RB_LIKELY(x) (__builtin_expect(!!(x), 1))
/**
* Asserts that the given Boolean expression likely doesn't hold.
*
* @param x An expression that likely doesn't hold.
*/
# define RB_UNLIKELY(x) (__builtin_expect(!!(x), 0))
#else
# define RB_LIKELY(x) (x)
# define RB_UNLIKELY(x) (x)
#endif
#endif /* RUBY_BACKWARD2_ASSUME_H */
include/ruby/backward/2/long_long.h 0000644 00000005720 15040330602 0013213 0 ustar 00 #ifndef RUBY_BACKWARD2_LONG_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_LONG_LONG_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines old #LONG_LONG
*
* No known compiler that can compile today's ruby lacks long long.
* Historically MSVC was one of such compiler, but it implemented long long a
* while ago (some time back in 2013). The macros are for backwards
* compatibility only.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/warning_push.h"
#if defined(__DOXYGEN__)
# /** @cond INTERNAL_MACRO */
# define HAVE_LONG_LONG 1
# define HAVE_TRUE_LONG_LONG 1
# /** @endcond */
# /** @deprecated Just use `long long` directly. */
# define LONG_LONG long long.
#elif RBIMPL_HAS_WARNING("-Wc++11-long-long")
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG \
RBIMPL_WARNING_PUSH() \
RBIMPL_WARNING_IGNORED(-Wc++11-long-long) \
long long \
RBIMPL_WARNING_POP()
#elif RBIMPL_HAS_WARNING("-Wlong-long")
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG \
RBIMPL_WARNING_PUSH() \
RBIMPL_WARNING_IGNORED(-Wlong-long) \
long long \
RBIMPL_WARNING_POP()
#elif defined(HAVE_LONG_LONG)
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG long long
#elif SIZEOF___INT64 > 0
# define HAVE_LONG_LONG 1
# define LONG_LONG __int64
# undef SIZEOF_LONG_LONG
# define SIZEOF_LONG_LONG SIZEOF___INT64
#else
# error Hello! Ruby developers believe this message must not happen.
# error If you encounter this message, can you file a bug report?
# error Remember to attach a detailed description of your environment.
# error Thank you!
#endif
#endif /* RBIMPL_BACKWARD2_LONG_LONG_H */
include/ruby/backward/2/attributes.h 0000644 00000012510 15040330602 0013416 0 ustar 00 #ifndef RUBY_BACKWARD2_ATTRIBUTES_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_ATTRIBUTES_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Various attribute-related macros.
*
* ### Q&A ###
*
* - Q: Why are the macros defined in this header file so inconsistent in
* style?
*
* - A: Don't know. Don't blame me. Backward compatibility is the key here.
* I'm just preserving what they have been.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/error.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/noinline.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/attr/warning.h"
#include "ruby/internal/has/attribute.h"
/* function attributes */
#undef CONSTFUNC
#define CONSTFUNC(x) RBIMPL_ATTR_CONST() x
#undef PUREFUNC
#define PUREFUNC(x) RBIMPL_ATTR_PURE() x
#undef DEPRECATED
#define DEPRECATED(x) RBIMPL_ATTR_DEPRECATED(("")) x
#undef DEPRECATED_BY
#define DEPRECATED_BY(n,x) RBIMPL_ATTR_DEPRECATED(("by: " # n)) x
#undef DEPRECATED_TYPE
#if defined(__GNUC__)
# define DEPRECATED_TYPE(mesg, decl) \
_Pragma("message \"DEPRECATED_TYPE is deprecated\""); \
decl RBIMPL_ATTR_DEPRECATED(mseg)
#elif defined(_MSC_VER)
# pragma deprecated(DEPRECATED_TYPE)
# define DEPRECATED_TYPE(mesg, decl) \
__pragma(message(__FILE__"("STRINGIZE(__LINE__)"): warning: " \
"DEPRECATED_TYPE is deprecated")) \
decl RBIMPL_ATTR_DEPRECATED(mseg)
#else
# define DEPRECATED_TYPE(mesg, decl) \
<-<-"DEPRECATED_TYPE is deprecated"->->
#endif
#undef RUBY_CXX_DEPRECATED
#define RUBY_CXX_DEPRECATED(mseg) RBIMPL_ATTR_DEPRECATED((mseg))
#undef NOINLINE
#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x
#ifndef MJIT_HEADER
# undef ALWAYS_INLINE
# define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
#endif
#undef ERRORFUNC
#define ERRORFUNC(mesg, x) RBIMPL_ATTR_ERROR(mesg) x
#if RBIMPL_HAS_ATTRIBUTE(error)
# define HAVE_ATTRIBUTE_ERRORFUNC 1
#endif
#undef WARNINGFUNC
#define WARNINGFUNC(mesg, x) RBIMPL_ATTR_WARNING(mesg) x
#if RBIMPL_HAS_ATTRIBUTE(warning)
# define HAVE_ATTRIBUTE_WARNINGFUNC 1
#endif
/*
cold attribute for code layout improvements
RUBY_FUNC_ATTRIBUTE not used because MSVC does not like nested func macros
*/
#undef COLDFUNC
#define COLDFUNC RBIMPL_ATTR_COLD()
#define PRINTF_ARGS(decl, string_index, first_to_check) \
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, (string_index), (first_to_check)) \
decl
#undef RUBY_ATTR_ALLOC_SIZE
#define RUBY_ATTR_ALLOC_SIZE RBIMPL_ATTR_ALLOC_SIZE
#undef RUBY_ATTR_MALLOC
#define RUBY_ATTR_MALLOC RBIMPL_ATTR_RESTRICT()
#undef RUBY_ATTR_RETURNS_NONNULL
#define RUBY_ATTR_RETURNS_NONNULL RBIMPL_ATTR_RETURNS_NONNULL()
#ifndef FUNC_MINIMIZED
#define FUNC_MINIMIZED(x) x
#endif
#ifndef FUNC_UNOPTIMIZED
#define FUNC_UNOPTIMIZED(x) x
#endif
#ifndef RUBY_ALIAS_FUNCTION_TYPE
#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) \
FUNC_MINIMIZED(type prot) {return (type)name args;}
#endif
#ifndef RUBY_ALIAS_FUNCTION_VOID
#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) \
FUNC_MINIMIZED(void prot) {name args;}
#endif
#ifndef RUBY_ALIAS_FUNCTION
#define RUBY_ALIAS_FUNCTION(prot, name, args) \
RUBY_ALIAS_FUNCTION_TYPE(VALUE, prot, name, args)
#endif
#undef RUBY_FUNC_NONNULL
#define RUBY_FUNC_NONNULL(n, x) RBIMPL_ATTR_NONNULL(n) x
#undef NORETURN
#define NORETURN(x) RBIMPL_ATTR_NORETURN() x
#define NORETURN_STYLE_NEW
#ifndef PACKED_STRUCT
# define PACKED_STRUCT(x) x
#endif
#ifndef PACKED_STRUCT_UNALIGNED
# if UNALIGNED_WORD_ACCESS
# define PACKED_STRUCT_UNALIGNED(x) PACKED_STRUCT(x)
# else
# define PACKED_STRUCT_UNALIGNED(x) x
# endif
#endif
#undef RB_UNUSED_VAR
#define RB_UNUSED_VAR(x) x RBIMPL_ATTR_MAYBE_UNUSED()
#endif /* RUBY_BACKWARD2_ATTRIBUTES_H */
include/ruby/backward/2/bool.h 0000644 00000003051 15040330602 0012163 0 ustar 00 #ifndef RUBY_BACKWARD2_BOOL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_BOOL_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines old TRUE / FALSE
*/
#include "ruby/internal/stdbool.h"
#ifndef FALSE
# define FALSE false
#elif FALSE
# error FALSE must be false
#endif
#ifndef TRUE
# define TRUE true
#elif ! TRUE
# error TRUE must be true
#endif
#endif /* RUBY_BACKWARD2_BOOL_H */
include/ruby/backward/cxxanyargs.hpp 0000644 00000074055 15040330602 0013632 0 ustar 00 #ifndef RUBY_BACKWARD_CXXANYARGS_HPP //-*-C++-*-vi:ft=cpp
#define RUBY_BACKWARD_CXXANYARGS_HPP
/// @file
/// @author @shyouhei
/// @copyright This file is a part of the programming language Ruby.
/// Permission is hereby granted, to either redistribute and/or
/// modify this file, provided that the conditions mentioned in the
/// file COPYING are met. Consult the file for details.
/// @note DO NOT MODERNISE THIS FILE! As the file name implies it is
/// meant to be a backwards compatibility shim. Please stick to
/// C++ 98 and never use newer features, like `constexpr`.
/// @brief Provides old prototypes for C++ programs.
#include "ruby/internal/config.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/cont.h"
#include "ruby/internal/intern/hash.h"
#include "ruby/internal/intern/proc.h"
#include "ruby/internal/intern/thread.h"
#include "ruby/internal/intern/variable.h"
#include "ruby/internal/intern/vm.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/method.h"
#include "ruby/internal/value.h"
#include "ruby/internal/variable.h"
#include "ruby/backward/2/stdarg.h"
#include "ruby/st.h"
extern "C++" {
#ifdef HAVE_NULLPTR
#include <cstddef>
#endif
/// @brief The main namespace.
/// @note The name "ruby" might already be taken, but that must not be a
/// problem because namespaces are allowed to reopen.
namespace ruby {
/// Backwards compatibility layer.
namespace backward {
/// Provides ANYARGS deprecation warnings. In C, ANYARGS means there is no
/// function prototype. Literally anything, even including nothing, can be a
/// valid ANYARGS. So passing a correctly prototyped function pointer to an
/// ANYARGS-ed function parameter is valid, at the same time passing an
/// ANYARGS-ed function pointer to a granular typed function parameter is also
/// valid. However on the other hand in C++, ANYARGS doesn't actually mean any
/// number of arguments. C++'s ANYARGS means _variadic_ number of arguments.
/// This is incompatible with ordinal, correct function prototypes.
///
/// Luckily, function prototypes being distinct each other means they can be
/// overloaded. We can provide a compatibility layer for older Ruby APIs which
/// used to have ANYARGS. This namespace includes such attempts.
namespace cxxanyargs {
typedef VALUE type(ANYARGS); ///< ANYARGS-ed function type.
typedef void void_type(ANYARGS); ///< ANYARGS-ed function type, void variant.
typedef int int_type(ANYARGS); ///< ANYARGS-ed function type, int variant.
typedef VALUE onearg_type(VALUE); ///< Single-argumented function type.
/// @name Hooking global variables
/// @{
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Define a function-backended global variable.
/// @param[in] q Name of the variable.
/// @param[in] w Getter function.
/// @param[in] e Setter function.
/// @note Both functions can be nullptr.
/// @see rb_define_hooked_variable()
/// @deprecated Use granular typed overload instead.
inline void
rb_define_virtual_variable(const char *q, type *w, void_type *e)
{
rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
::rb_define_virtual_variable(q, r, t);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, void_type *e)
{
rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
::rb_define_virtual_variable(q, w, t);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, type *w, rb_gvar_setter_t *e)
{
rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
::rb_define_virtual_variable(q, r, e);
}
#ifdef HAVE_NULLPTR
inline void
rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, std::nullptr_t e)
{
::rb_define_virtual_variable(q, w, e);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, type *w, std::nullptr_t e)
{
rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t *>(w);
::rb_define_virtual_variable(q, r, e);
}
inline void
rb_define_virtual_variable(const char *q, std::nullptr_t w, rb_gvar_setter_t *e)
{
::rb_define_virtual_variable(q, w, e);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, std::nullptr_t w, void_type *e)
{
rb_gvar_setter_t *r = reinterpret_cast<rb_gvar_setter_t *>(e);
::rb_define_virtual_variable(q, w, r);
}
#endif
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Define a function-backended global variable.
/// @param[in] q Name of the variable.
/// @param[in] w Variable storage.
/// @param[in] e Getter function.
/// @param[in] r Setter function.
/// @note Both functions can be nullptr.
/// @see rb_define_virtual_variable()
/// @deprecated Use granular typed overload instead.
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
{
rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
::rb_define_hooked_variable(q, w, t, y);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, void_type *r)
{
rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
::rb_define_hooked_variable(q, w, e, y);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, rb_gvar_setter_t *r)
{
rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
::rb_define_hooked_variable(q, w, t, r);
}
#ifdef HAVE_NULLPTR
inline void
rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, std::nullptr_t r)
{
::rb_define_hooked_variable(q, w, e, r);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, std::nullptr_t r)
{
rb_gvar_getter_t *y = reinterpret_cast<rb_gvar_getter_t *>(e);
::rb_define_hooked_variable(q, w, y, r);
}
inline void
rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, rb_gvar_setter_t *r)
{
::rb_define_hooked_variable(q, w, e, r);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, void_type *r)
{
rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t *>(r);
::rb_define_hooked_variable(q, w, e, y);
}
#endif
/// @}
/// @name Exceptions and tag jumps
/// @{
// RUBY_CXX_DEPRECATED("by rb_block_call since 1.9")
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Old way to implement iterators.
/// @param[in] q A function that can yield.
/// @param[in] w Passed to `q`.
/// @param[in] e What is to be yielded.
/// @param[in] r Passed to `e`.
/// @return The return value of `q`.
/// @note `e` can be nullptr.
/// @deprecated This function is obsoleted since long before 2.x era. Do not
/// use it any longer. rb_block_call() is provided instead.
inline VALUE
rb_iterate(onearg_type *q, VALUE w, type *e, VALUE r)
{
rb_block_call_func_t t = reinterpret_cast<rb_block_call_func_t>(e);
return backward::rb_iterate_deprecated(q, w, t, r);
}
#ifdef HAVE_NULLPTR
RUBY_CXX_DEPRECATED("by rb_block_call since 1.9")
inline VALUE
rb_iterate(onearg_type *q, VALUE w, std::nullptr_t e, VALUE r)
{
return backward::rb_iterate_deprecated(q, w, e, r);
}
#endif
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Call a method with a block.
/// @param[in] q The self.
/// @param[in] w The method.
/// @param[in] e The # of elems of `r`
/// @param[in] r The arguments.
/// @param[in] t What is to be yielded.
/// @param[in] y Passed to `t`
/// @return Return value of `q#w(*r,&t)`
/// @note 't' can be nullptr.
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
{
rb_block_call_func_t u = reinterpret_cast<rb_block_call_func_t>(t);
return ::rb_block_call(q, w, e, r, u, y);
}
#ifdef HAVE_NULLPTR
inline VALUE
rb_block_call(VALUE q, ID w, int e, const VALUE *r, std::nullptr_t t, VALUE y)
{
return ::rb_block_call(q, w, e, r, t, y);
}
#endif
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief An equivalent of `rescue` clause.
/// @param[in] q A function that can raise.
/// @param[in] w Passed to `q`.
/// @param[in] e A function that cleans-up.
/// @param[in] r Passed to `e`.
/// @return The return value of `q` if no exception occurs, or the return
/// value of `e` if otherwise.
/// @note `e` can be nullptr.
/// @see rb_ensure()
/// @see rb_rescue2()
/// @see rb_protect()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_rescue(type *q, VALUE w, type *e, VALUE r)
{
typedef VALUE func1_t(VALUE);
typedef VALUE func2_t(VALUE, VALUE);
func1_t *t = reinterpret_cast<func1_t*>(q);
func2_t *y = reinterpret_cast<func2_t*>(e);
return ::rb_rescue(t, w, y, r);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief An equivalent of `rescue` clause.
/// @param[in] q A function that can raise.
/// @param[in] w Passed to `q`.
/// @param[in] e A function that cleans-up.
/// @param[in] r Passed to `e`.
/// @param[in] ... 0-terminated list of subclass of @ref rb_eException.
/// @return The return value of `q` if no exception occurs, or the return
/// value of `e` if otherwise.
/// @note `e` can be nullptr.
/// @see rb_ensure()
/// @see rb_rescue()
/// @see rb_protect()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_rescue2(type *q, VALUE w, type *e, VALUE r, ...)
{
typedef VALUE func1_t(VALUE);
typedef VALUE func2_t(VALUE, VALUE);
func1_t *t = reinterpret_cast<func1_t*>(q);
func2_t *y = reinterpret_cast<func2_t*>(e);
va_list ap;
va_start(ap, r);
VALUE ret = ::rb_vrescue2(t, w, y, r, ap);
va_end(ap);
return ret;
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief An equivalent of `ensure` clause.
/// @param[in] q A function that can raise.
/// @param[in] w Passed to `q`.
/// @param[in] e A function that ensures.
/// @param[in] r Passed to `e`.
/// @return The return value of `q`.
/// @note It makes no sense to pass nullptr to `e`.
/// @see rb_rescue()
/// @see rb_rescue2()
/// @see rb_protect()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_ensure(type *q, VALUE w, type *e, VALUE r)
{
typedef VALUE func1_t(VALUE);
func1_t *t = reinterpret_cast<func1_t*>(q);
func1_t *y = reinterpret_cast<func1_t*>(e);
return ::rb_ensure(t, w, y, r);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief An equivalent of `Kernel#catch`.
/// @param[in] q The "tag" string.
/// @param[in] w A function that can throw.
/// @param[in] e Passed to `w`.
/// @return What was thrown.
/// @note `q` can be a nullptr but makes no sense to pass nullptr to`w`.
/// @see rb_block_call()
/// @see rb_protect()
/// @see rb_rb_catch_obj()
/// @see rb_rescue()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_catch(const char *q, type *w, VALUE e)
{
rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
return ::rb_catch(q, r, e);
}
#ifdef HAVE_NULLPTR
inline VALUE
rb_catch(const char *q, std::nullptr_t w, VALUE e)
{
return ::rb_catch(q, w, e);
}
#endif
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief An equivalent of `Kernel#catch`.
/// @param[in] q The "tag" object.
/// @param[in] w A function that can throw.
/// @param[in] e Passed to `w`.
/// @return What was thrown.
/// @note It makes no sense to pass nullptr to`w`.
/// @see rb_block_call()
/// @see rb_protect()
/// @see rb_rb_catch_obj()
/// @see rb_rescue()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_catch_obj(VALUE q, type *w, VALUE e)
{
rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
return ::rb_catch_obj(q, r, e);
}
/// @}
/// @name Procs, Fibers and Threads
/// @{
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Creates a rb_cFiber instance.
/// @param[in] q The fiber body.
/// @param[in] w Passed to `q`.
/// @return What was allocated.
/// @note It makes no sense to pass nullptr to`q`.
/// @see rb_proc_new()
/// @see rb_thread_create()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_fiber_new(type *q, VALUE w)
{
rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
return ::rb_fiber_new(e, w);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Creates a @ref rb_cProc instance.
/// @param[in] q The proc body.
/// @param[in] w Passed to `q`.
/// @return What was allocated.
/// @note It makes no sense to pass nullptr to`q`.
/// @see rb_fiber_new()
/// @see rb_thread_create()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_proc_new(type *q, VALUE w)
{
rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
return ::rb_proc_new(e, w);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Creates a @ref rb_cThread instance.
/// @param[in] q The thread body.
/// @param[in] w Passed to `q`.
/// @return What was allocated.
/// @note It makes no sense to pass nullptr to`q`.
/// @see rb_proc_new()
/// @see rb_fiber_new()
/// @deprecated Use granular typed overload instead.
inline VALUE
rb_thread_create(type *q, void *w)
{
typedef VALUE ptr_t(void*);
ptr_t *e = reinterpret_cast<ptr_t*>(q);
return ::rb_thread_create(e, w);
}
/// @}
/// @name Hash and st_table
/// @{
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Iteration over the given table.
/// @param[in] q A table to scan.
/// @param[in] w A function to iterate.
/// @param[in] e Passed to `w`.
/// @retval 0 Always returns 0.
/// @note It makes no sense to pass nullptr to`w`.
/// @see st_foreach_check()
/// @see rb_hash_foreach()
/// @deprecated Use granular typed overload instead.
inline int
st_foreach(st_table *q, int_type *w, st_data_t e)
{
st_foreach_callback_func *r =
reinterpret_cast<st_foreach_callback_func*>(w);
return ::st_foreach(q, r, e);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Iteration over the given table.
/// @param[in] q A table to scan.
/// @param[in] w A function to iterate.
/// @param[in] e Passed to `w`.
/// @retval 0 Successful end of iteration.
/// @retval 1 Element removed during traversing.
/// @note It makes no sense to pass nullptr to`w`.
/// @see st_foreach()
/// @deprecated Use granular typed overload instead.
inline int
st_foreach_check(st_table *q, int_type *w, st_data_t e, st_data_t)
{
st_foreach_check_callback_func *t =
reinterpret_cast<st_foreach_check_callback_func*>(w);
return ::st_foreach_check(q, t, e, 0);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Iteration over the given table.
/// @param[in] q A table to scan.
/// @param[in] w A function to iterate.
/// @param[in] e Passed to `w`.
/// @note It makes no sense to pass nullptr to`w`.
/// @see st_foreach_check()
/// @deprecated Use granular typed overload instead.
inline void
st_foreach_safe(st_table *q, int_type *w, st_data_t e)
{
st_foreach_callback_func *r =
reinterpret_cast<st_foreach_callback_func*>(w);
::st_foreach_safe(q, r, e);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Iteration over the given hash.
/// @param[in] q A hash to scan.
/// @param[in] w A function to iterate.
/// @param[in] e Passed to `w`.
/// @note It makes no sense to pass nullptr to`w`.
/// @see st_foreach()
/// @deprecated Use granular typed overload instead.
inline void
rb_hash_foreach(VALUE q, int_type *w, VALUE e)
{
st_foreach_callback_func *r =
reinterpret_cast<st_foreach_callback_func*>(w);
::rb_hash_foreach(q, r, e);
}
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief Iteration over each instance variable of the object.
/// @param[in] q An object.
/// @param[in] w A function to iterate.
/// @param[in] e Passed to `w`.
/// @note It makes no sense to pass nullptr to`w`.
/// @see st_foreach()
/// @deprecated Use granular typed overload instead.
inline void
rb_ivar_foreach(VALUE q, int_type *w, VALUE e)
{
st_foreach_callback_func *r =
reinterpret_cast<st_foreach_callback_func*>(w);
::rb_ivar_foreach(q, r, e);
}
/// @}
/// Driver for *_define_method. ::rb_define_method function for instance takes
/// a pointer to ANYARGS-ed functions, which in fact varies 18 different
/// prototypes. We still need to preserve ANYARGS for storages but why not
/// check the consistencies if possible. In C++ a function has its own
/// prototype, which is a compile-time constant (static type) by nature. We
/// can list up all the possible input types and provide warnings for other
/// cases. This is such attempt.
namespace define_method {
/// Type of ::rb_f_notimplement().
typedef VALUE notimpl_type(int, const VALUE *, VALUE, VALUE);
/// @brief Template metaprogramming to generate function prototypes.
/// @tparam T Type of method id (`ID` or `const char*` in practice).
/// @tparam F Definition driver e.g. ::rb_define_method.
template<typename T, void (*F)(VALUE klass, T mid, type *func, int arity)>
struct driver {
/// @brief Defines a method
/// @tparam N Arity of the function.
/// @tparam U The function in question
template<int N, typename U>
struct engine {
/* :TODO: Following deprecation attribute renders tons of warnings (one
* per every method definitions), which is annoying. Of course
* annoyance is the core feature of deprecation warnings... But that
* could be too much, especially when the warnings happen inside of
* machine-generated programs. And SWIG is known to do such thing.
* The new (granular) API was introduced in API version 2.7. As of
* this writing the version is 2.8. Let's warn this later, some time
* during 3.x. Hopefully codes in old (ANYARGS-ed) format should be
* less than now. */
#if (RUBY_API_VERSION_MAJOR * 100 + RUBY_API_VERSION_MINOR) >= 301
RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
#endif
/// @copydoc define(VALUE klass, T mid, U func)
/// @deprecated Pass correctly typed function instead.
static inline void
define(VALUE klass, T mid, type func)
{
F(klass, mid, func, N);
}
/// @brief Defines klass#mid as func, whose arity is N.
/// @param[in] klass Where the method lives.
/// @param[in] mid Name of the method to define.
/// @param[in] func Function that implements klass#mid.
static inline void
define(VALUE klass, T mid, U func)
{
F(klass, mid, reinterpret_cast<type *>(func), N);
}
/// @copydoc define(VALUE klass, T mid, U func)
static inline void
define(VALUE klass, T mid, notimpl_type func)
{
F(klass, mid, reinterpret_cast<type *>(func), N);
}
};
/// @cond INTERNAL_MACRO
template<int N, bool = false> struct specific : public engine<N, type *> {};
template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
static inline void define(VALUE c, T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(c, m, reinterpret_cast<type *>(f), -1); }
};
template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
/// @endcond
};
/* We could perhaps merge this struct into the one above using variadic
* template parameters if we could assume C++11, but sadly we cannot. */
/// @copydoc ruby::backward::cxxanyargs::define_method::driver
template<typename T, void (*F)(T mid, type func, int arity)>
struct driver0 {
/// @brief Defines a method
/// @tparam N Arity of the function.
/// @tparam U The function in question
template<int N, typename U>
struct engine {
RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
/// @copydoc define(T mid, U func)
/// @deprecated Pass correctly typed function instead.
static inline void
define(T mid, type func)
{
F(mid, func, N);
}
/// @brief Defines Kernel#mid as func, whose arity is N.
/// @param[in] mid Name of the method to define.
/// @param[in] func Function that implements klass#mid.
static inline void
define(T mid, U func)
{
F(mid, reinterpret_cast<type *>(func), N);
}
/// @copydoc define(T mid, U func)
/// @deprecated Pass correctly typed function instead.
static inline void
define(T mid, notimpl_type func)
{
F(mid, reinterpret_cast<type *>(func), N);
}
};
/// @cond INTERNAL_MACRO
template<int N, bool = false> struct specific : public engine<N, type *> {};
template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
static inline void define(T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(m, reinterpret_cast<type *>(f), -1); }
};
template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
/// @endcond
};
struct rb_define_method : public driver <const char *, ::rb_define_method> {}; ///< Dispatches appropriate driver for ::rb_define_method.
struct rb_define_method_id : public driver <ID, ::rb_define_method_id> {}; ///< Dispatches appropriate driver for ::rb_define_method_id.
struct rb_define_private_method : public driver <const char *, ::rb_define_private_method> {}; ///< Dispatches appropriate driver for ::rb_define_private_method.
struct rb_define_protected_method : public driver <const char *, ::rb_define_protected_method> {}; ///< Dispatches appropriate driver for ::rb_define_protected_method.
struct rb_define_singleton_method : public driver <const char *, ::rb_define_singleton_method> {}; ///< Dispatches appropriate driver for ::rb_define_singleton_method.
struct rb_define_module_function : public driver <const char *, ::rb_define_module_function> {}; ///< Dispatches appropriate driver for ::rb_define_module_function.
struct rb_define_global_function : public driver0<const char *, ::rb_define_global_function> {}; ///< Dispatches appropriate driver for ::rb_define_global_function.
/// @brief Defines klass\#mid.
/// @param klass Where the method lives.
/// @copydetails #rb_define_global_function(mid, func, arity)
#define rb_define_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_method::specific<arity>::define(klass, mid, func)
/// @copydoc #rb_define_method(klass, mid, func, arity)
#define rb_define_method_id(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_method_id::specific<arity>::define(klass, mid, func)
/// @brief Defines klass\#mid and makes it private.
/// @copydetails #rb_define_method(klass, mid, func, arity)
#define rb_define_private_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_private_method::specific<arity>::define(klass, mid, func)
/// @brief Defines klass\#mid and makes it protected.
/// @copydetails #rb_define_method
#define rb_define_protected_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method::specific<arity>::define(klass, mid, func)
/// @brief Defines klass.mid.(klass, mid, func, arity)
/// @copydetails #rb_define_method
#define rb_define_singleton_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_singleton_method::specific<arity>::define(klass, mid, func)
/// @brief Defines klass\#mid and makes it a module function.
/// @copydetails #rb_define_method(klass, mid, func, arity)
#define rb_define_module_function(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_module_function::specific<arity>::define(klass, mid, func)
/// @brief Defines ::rb_mKernel \#mid.
/// @param mid Name of the defining method.
/// @param func Implementation of \#mid.
/// @param arity Arity of \#mid.
#define rb_define_global_function(mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_global_function::specific<arity>::define(mid, func)
}}}}}
using namespace ruby::backward::cxxanyargs;
#endif // RUBY_BACKWARD_CXXANYARGS_HPP
include/ruby/intern.h 0000644 00000004532 15040330602 0010615 0 ustar 00 #ifndef RUBY_INTERN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERN_H 1
/**
* @file
* @author $Author$
* @date Thu Jun 10 14:22:17 JST 1993
* @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
* @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
* @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/config.h"
#include "ruby/defines.h"
#include <stdarg.h>
#include "ruby/st.h"
/*
* Functions and variables that are used by more than one source file of
* the kernel.
*/
#include "ruby/internal/intern/array.h"
#include "ruby/internal/intern/bignum.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/compar.h"
#include "ruby/internal/intern/complex.h"
#include "ruby/internal/intern/cont.h"
#include "ruby/internal/intern/dir.h"
#include "ruby/internal/intern/enum.h"
#include "ruby/internal/intern/enumerator.h"
#include "ruby/internal/intern/error.h"
#include "ruby/internal/intern/eval.h"
#include "ruby/internal/intern/file.h"
#include "ruby/internal/intern/gc.h"
#include "ruby/internal/intern/hash.h"
#include "ruby/internal/intern/io.h"
#include "ruby/internal/intern/load.h"
#include "ruby/internal/intern/marshal.h"
#include "ruby/internal/intern/numeric.h"
#include "ruby/internal/intern/object.h"
#include "ruby/internal/intern/parse.h"
#include "ruby/internal/intern/proc.h"
#include "ruby/internal/intern/process.h"
#include "ruby/internal/intern/random.h"
#include "ruby/internal/intern/range.h"
#include "ruby/internal/intern/rational.h"
#include "ruby/internal/intern/re.h"
#include "ruby/internal/intern/ruby.h"
#include "ruby/internal/intern/select.h"
#include "ruby/internal/intern/signal.h"
#include "ruby/internal/intern/sprintf.h"
#include "ruby/internal/intern/string.h"
#include "ruby/internal/intern/struct.h"
#include "ruby/internal/intern/thread.h"
#include "ruby/internal/intern/time.h"
#include "ruby/internal/intern/variable.h"
#include "ruby/internal/intern/vm.h"
#endif /* RUBY_INTERN_H */
include/ruby/encoding.h 0000644 00000002440 15040330602 0011100 0 ustar 00 #ifndef RUBY_ENCODING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ENCODING_H 1
/**
* @file
* @author $Author: matz $
* @date Thu May 24 11:49:41 JST 2007
* @copyright Copyright (C) 2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @brief Encoding relates APIs.
*
* These APIs are mainly for implementing encodings themselves. Encodings are
* built on top of Ruby's core CAPIs. Though not prohibited, there can be
* relatively less rooms for things in this header file be useful when writing
* an extension library.
*/
#include "ruby/ruby.h"
#include "ruby/internal/encoding/coderange.h"
#include "ruby/internal/encoding/ctype.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/encoding/pathname.h"
#include "ruby/internal/encoding/re.h"
#include "ruby/internal/encoding/sprintf.h"
#include "ruby/internal/encoding/string.h"
#include "ruby/internal/encoding/symbol.h"
#include "ruby/internal/encoding/transcode.h"
#endif /* RUBY_ENCODING_H */
include/ruby/memory_view.h 0000644 00000025454 15040330602 0011666 0 ustar 00 #ifndef RUBY_MEMORY_VIEW_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_MEMORY_VIEW_H 1
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @brief Memory View.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h> /* size_t */
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
#include "ruby/internal/attr/pure.h" /* RBIMPL_ATTR_PURE */
#include "ruby/internal/core/rtypeddata.h" /* rb_data_type_t */
#include "ruby/internal/dllexport.h" /* RUBY_EXTERN */
#include "ruby/internal/stdbool.h" /* bool */
#include "ruby/internal/value.h" /* VALUE */
/**
* Flags passed to rb_memory_view_get(), then to ::rb_memory_view_get_func_t.
*/
enum ruby_memory_view_flags {
RUBY_MEMORY_VIEW_SIMPLE = 0,
RUBY_MEMORY_VIEW_WRITABLE = (1<<0),
RUBY_MEMORY_VIEW_FORMAT = (1<<1),
RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL = (1<<2),
RUBY_MEMORY_VIEW_STRIDES = (1<<3) | RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL,
RUBY_MEMORY_VIEW_ROW_MAJOR = (1<<4) | RUBY_MEMORY_VIEW_STRIDES,
RUBY_MEMORY_VIEW_COLUMN_MAJOR = (1<<5) | RUBY_MEMORY_VIEW_STRIDES,
RUBY_MEMORY_VIEW_ANY_CONTIGUOUS = RUBY_MEMORY_VIEW_ROW_MAJOR | RUBY_MEMORY_VIEW_COLUMN_MAJOR,
RUBY_MEMORY_VIEW_INDIRECT = (1<<6) | RUBY_MEMORY_VIEW_STRIDES,
};
/** Memory view component metadata. */
typedef struct {
/** @see ::rb_memory_view_t::format */
char format;
/** :FIXME: what is a "native" size is unclear. */
unsigned native_size_p: 1;
/** Endian of the component */
unsigned little_endian_p: 1;
/** The component's offset. */
size_t offset;
/** The component's size. */
size_t size;
/**
* How many numbers of components are there. For instance "CCC"'s repeat is
* 3.
*/
size_t repeat;
} rb_memory_view_item_component_t;
/**
* A MemoryView structure, `rb_memory_view_t`, is used for exporting objects'
* MemoryView.
*
* This structure contains the reference of the object, which is the owner of
* the MemoryView, the pointer to the head of exported memory, and the metadata
* that describes the structure of the memory. The metadata can describe
* multidimensional arrays with strides.
*/
typedef struct {
/**
* The original object that has the memory exported via this memory view.
*/
VALUE obj;
/** The pointer to the exported memory. */
void *data;
/** The number of bytes in data. */
ssize_t byte_size;
/** true for readonly memory, false for writable memory. */
bool readonly;
/**
* A string to describe the format of an element, or NULL for unsigned bytes.
* The format string is a sequence of the following pack-template specifiers:
*
* c, C, s, s!, S, S!, n, v, i, i!, I, I!, l, l!, L, L!,
* N, V, f, e, g, q, q!, Q, Q!, d, E, G, j, J, x
*
* For example, "dd" for an element that consists of two double values,
* and "CCC" for an element that consists of three bytes, such as
* an RGB color triplet.
*
* Also, the value endianness can be explicitly specified by '<' or '>'
* following a value type specifier.
*
* The items are packed contiguously. When you emulate the alignment of
* structure members, put '|' at the beginning of the format string,
* like "|iqc". On x86_64 Linux ABI, the size of the item by this format
* is 24 bytes instead of 13 bytes.
*/
const char *format;
/**
* The number of bytes in each element.
* item_size should equal to rb_memory_view_item_size_from_format(format). */
ssize_t item_size;
/** Description of each components. */
struct {
/**
* The array of rb_memory_view_item_component_t that describes the
* item structure. rb_memory_view_prepare_item_desc and
* rb_memory_view_get_item allocate this memory if needed,
* and rb_memory_view_release frees it. */
const rb_memory_view_item_component_t *components;
/** The number of components in an item. */
size_t length;
} item_desc;
/** The number of dimension. */
ssize_t ndim;
/**
* ndim size array indicating the number of elements in each dimension.
* This can be NULL when ndim == 1. */
const ssize_t *shape;
/**
* ndim size array indicating the number of bytes to skip to go to the
* next element in each dimension. */
const ssize_t *strides;
/**
* The offset in each dimension when this memory view exposes a nested array.
* Or, NULL when this memory view exposes a flat array. */
const ssize_t *sub_offsets;
/** The private data for managing this exported memory */
void *private_data;
/** DO NOT TOUCH THIS: The memory view entry for the internal use */
const struct rb_memory_view_entry *_memory_view_entry;
} rb_memory_view_t;
/** Type of function of ::rb_memory_view_entry_t::get_func. */
typedef bool (* rb_memory_view_get_func_t)(VALUE obj, rb_memory_view_t *view, int flags);
/** Type of function of ::rb_memory_view_entry_t::release_func. */
typedef bool (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view);
/** Type of function of ::rb_memory_view_entry_t::available_p_func. */
typedef bool (* rb_memory_view_available_p_func_t)(VALUE obj);
/** Operations applied to a specific kind of a memory view. */
typedef struct rb_memory_view_entry {
/**
* Exports a memory view from a Ruby object.
*/
rb_memory_view_get_func_t get_func;
/**
* Releases a memory view that was previously generated using
* ::rb_memory_view_entry_t::get_func.
*/
rb_memory_view_release_func_t release_func;
/**
* Queries if an object understands memory view protocol.
*/
rb_memory_view_available_p_func_t available_p_func;
} rb_memory_view_entry_t;
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* memory_view.c */
/**
* Associates the passed class with the passed memory view entry. This has to
* be called before actually creating a memory view from an instance.
*/
bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry);
RBIMPL_ATTR_PURE()
/**
* Return `true` if the data in the MemoryView `view` is row-major contiguous.
*
* Return `false` otherwise.
*/
bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view);
RBIMPL_ATTR_PURE()
/**
* Return `true` if the data in the MemoryView `view` is column-major
* contiguous.
*
* Return `false` otherwise.
*/
bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view);
RBIMPL_ATTR_NOALIAS()
/**
* Fill the `strides` array with byte-Strides of a contiguous array of the
* given shape with the given element size.
*/
void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides);
RBIMPL_ATTR_NOALIAS()
/**
* Fill the members of `view` as an 1-dimensional byte array.
*/
bool rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly);
/**
* Deconstructs the passed format string, as describe in
* ::rb_memory_view_t::format.
*/
ssize_t rb_memory_view_parse_item_format(const char *format,
rb_memory_view_item_component_t **members,
size_t *n_members, const char **err);
/**
* Calculate the number of bytes occupied by an element.
*
* When the calculation fails, the failed location in `format` is stored into
* `err`, and returns `-1`.
*/
ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err);
/**
* Calculate the location of the item indicated by the given `indices`.
*
* The length of `indices` must equal to `view->ndim`.
*
* This function initializes `view->item_desc` if needed.
*/
void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices);
/**
* Return a value that consists of item members.
*
* When an item is a single member, the return value is a single value.
*
* When an item consists of multiple members, an array will be returned.
*/
VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members);
/** Fill the `item_desc` member of `view`. */
void rb_memory_view_prepare_item_desc(rb_memory_view_t *view);
/** * Return a value that consists of item members in the given memory view. */
VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices);
/**
* Return `true` if `obj` supports to export a MemoryView. Return `false`
* otherwise.
*
* If this function returns `true`, it doesn't mean the function
* `rb_memory_view_get` will succeed.
*/
bool rb_memory_view_available_p(VALUE obj);
/**
* If the given `obj` supports to export a MemoryView that conforms the given
* `flags`, this function fills `view` by the information of the MemoryView and
* returns `true`. In this case, the reference count of `obj` is increased.
*
* If the given combination of `obj` and `flags` cannot export a MemoryView,
* this function returns `false`. The content of `view` is not touched in this
* case.
*
* The exported MemoryView must be released by `rb_memory_view_release` when
* the MemoryView is no longer needed.
*/
bool rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags);
/**
* Release the given MemoryView `view` and decrement the reference count of
* `memory_view->obj`.
*
* Consumers must call this function when the MemoryView is no longer needed.
* Missing to call this function leads memory leak.
*/
bool rb_memory_view_release(rb_memory_view_t* memory_view);
/* for testing */
/** @cond INTERNAL_MACRO */
RUBY_EXTERN VALUE rb_memory_view_exported_object_registry;
RUBY_EXTERN const rb_data_type_t rb_memory_view_exported_object_registry_data_type;
/** @endcond */
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE()
/**
* Return `true` if the data in the MemoryView `view` is row-major or
* column-major contiguous.
*
* Return `false` otherwise.
*/
static inline bool
rb_memory_view_is_contiguous(const rb_memory_view_t *view)
{
if (rb_memory_view_is_row_major_contiguous(view)) {
return true;
}
else if (rb_memory_view_is_column_major_contiguous(view)) {
return true;
}
else {
return false;
}
}
#endif /* RUBY_BUFFER_H */
include/ruby/defines.h 0000644 00000005406 15040330602 0010734 0 ustar 00 #ifndef RUBY_DEFINES_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_DEFINES_H 1
/**
* @file
* @author $Author$
* @date Wed May 18 00:21:44 JST 1994
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/config.h"
/* AC_INCLUDES_DEFAULT */
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#ifdef HAVE_STDALIGN_H
# include <stdalign.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef RUBY_USE_SETJMPEX
# include <setjmpex.h>
#endif
#include "ruby/internal/dllexport.h"
#include "ruby/internal/xmalloc.h"
#include "ruby/backward/2/assume.h"
#include "ruby/backward/2/attributes.h"
#include "ruby/backward/2/bool.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/stdalign.h"
#include "ruby/backward/2/stdarg.h"
#include "ruby/internal/dosish.h"
#include "ruby/missing.h"
/**
* Asserts that the compilation unit includes Ruby's CAPI. This has been here
* since the very beginning (at least since version 0.49).
*/
#define RUBY
#ifdef __GNUC__
# /** This is expanded to nothing for non-GCC compilers. */
# define RB_GNUC_EXTENSION __extension__
# /** This is expanded to the passed token for non-GCC compilers. */
# define RB_GNUC_EXTENSION_BLOCK(x) __extension__ ({ x; })
#else
# define RB_GNUC_EXTENSION
# define RB_GNUC_EXTENSION_BLOCK(x) (x)
#endif
/** @cond INTERNAL_MACRO */
/* :FIXME: Can someone tell us why is this macro defined here? @shyouhei
* thinks this is a truly internal macro but cannot move around because he
* doesn't understand the reason of this arrangement. */
#ifndef RUBY_MBCHAR_MAXSIZE
# define RUBY_MBCHAR_MAXSIZE INT_MAX
# /* MB_CUR_MAX will not work well in C locale */
#endif
#if defined(__sparc)
RBIMPL_SYMBOL_EXPORT_BEGIN()
void rb_sparc_flush_register_windows(void);
RBIMPL_SYMBOL_EXPORT_END()
# define FLUSH_REGISTER_WINDOWS rb_sparc_flush_register_windows()
#else
# define FLUSH_REGISTER_WINDOWS ((void)0)
#endif
/** @endcond */
#endif /* RUBY_DEFINES_H */
include/ruby/io.h 0000644 00000105253 15040330602 0007727 0 ustar 00 #ifndef RUBY_IO_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_IO_H 1
/**
* @file
* @author $Author$
* @date Fri Nov 12 16:47:09 JST 1993
* @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/config.h"
#include <stdio.h>
#include "ruby/encoding.h"
#if defined(HAVE_STDIO_EXT_H)
#include <stdio_ext.h>
#endif
#include <errno.h>
/** @cond INTERNAL_MACRO */
#if defined(HAVE_POLL)
# ifdef _AIX
# define reqevents events
# define rtnevents revents
# endif
# include <poll.h>
# ifdef _AIX
# undef reqevents
# undef rtnevents
# undef events
# undef revents
# endif
# define RB_WAITFD_IN POLLIN
# if defined(POLLPRI)
# define RB_WAITFD_PRI POLLPRI
# else
# define RB_WAITFD_PRI 0
# endif
# define RB_WAITFD_OUT POLLOUT
#else
# define RB_WAITFD_IN 0x001
# define RB_WAITFD_PRI 0x002
# define RB_WAITFD_OUT 0x004
#endif
/** @endcond */
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/attributes.h" /* PACKED_STRUCT_UNALIGNED */
// IO#wait, IO#wait_readable, IO#wait_writable, IO#wait_priority are defined by this implementation.
#define RUBY_IO_WAIT_METHODS
// Used as the default timeout argument to `rb_io_wait` to use the `IO#timeout` value.
#define RUBY_IO_TIMEOUT_DEFAULT Qnil
RBIMPL_SYMBOL_EXPORT_BEGIN()
struct stat;
struct timeval;
/**
* Indicates that a timeout has occurred while performing an IO operation.
*/
RUBY_EXTERN VALUE rb_eIOTimeoutError;
/**
* Type of events that an IO can wait.
*
* @internal
*
* This is visible from extension libraries because `io/wait` wants it.
*/
typedef enum {
RUBY_IO_READABLE = RB_WAITFD_IN, /**< `IO::READABLE` */
RUBY_IO_WRITABLE = RB_WAITFD_OUT, /**< `IO::WRITABLE` */
RUBY_IO_PRIORITY = RB_WAITFD_PRI, /**< `IO::PRIORITY` */
} rb_io_event_t;
/**
* IO buffers. This is an implementation detail of ::rb_io_t::wbuf and
* ::rb_io_t::rbuf. People don't manipulate it directly.
*/
PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t {
/** Pointer to the underlying memory region, of at least `capa` bytes. */
char *ptr; /* off + len <= capa */
/** Offset inside of `ptr`. */
int off;
/** Length of the buffer. */
int len;
/** Designed capacity of the buffer. */
int capa;
});
/** @alias{rb_io_buffer_t} */
typedef struct rb_io_buffer_t rb_io_buffer_t;
/** Decomposed encoding flags (e.g. `"enc:enc2""`). */
/*
* enc enc2 read action write action
* NULL NULL force_encoding(default_external) write the byte sequence of str
* e1 NULL force_encoding(e1) convert str.encoding to e1
* e1 e2 convert from e2 to e1 convert str.encoding to e2
*/
struct rb_io_enc_t {
/** Internal encoding. */
rb_encoding *enc;
/** External encoding. */
rb_encoding *enc2;
/**
* Flags.
*
* @see enum ::ruby_econv_flag_type
*/
int ecflags;
/**
* Flags as Ruby hash.
*
* @internal
*
* This is set. But used from nowhere maybe?
*/
VALUE ecopts;
};
/** Ruby's IO, metadata and buffers. */
typedef struct rb_io_t {
/** The IO's Ruby level counterpart. */
VALUE self;
/** stdio ptr for read/write, if available. */
FILE *stdio_file;
/** file descriptor. */
int fd;
/** mode flags: FMODE_XXXs */
int mode;
/** child's pid (for pipes) */
rb_pid_t pid;
/** number of lines read */
int lineno;
/** pathname for file */
VALUE pathv;
/** finalize proc */
void (*finalize)(struct rb_io_t*,int);
/** Write buffer. */
rb_io_buffer_t wbuf;
/**
* (Byte) read buffer. Note also that there is a field called
* ::rb_io_t::cbuf, which also concerns read IO.
*/
rb_io_buffer_t rbuf;
/**
* Duplex IO object, if set.
*
* @see rb_io_set_write_io()
*/
VALUE tied_io_for_writing;
struct rb_io_enc_t encs; /**< Decomposed encoding flags. */
/** Encoding converter used when reading from this IO. */
rb_econv_t *readconv;
/**
* rb_io_ungetc() destination. This buffer is read before checking
* ::rb_io_t::rbuf
*/
rb_io_buffer_t cbuf;
/** Encoding converter used when writing to this IO. */
rb_econv_t *writeconv;
/**
* This is, when set, an instance of ::rb_cString which holds the "common"
* encoding. Write conversion can convert strings twice... In case
* conversion from encoding X to encoding Y does not exist, Ruby finds an
* encoding Z that bridges the two, so that X to Z to Y conversion happens.
*/
VALUE writeconv_asciicompat;
/** Whether ::rb_io_t::writeconv is already set up. */
int writeconv_initialized;
/**
* Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before
* initialising ::rb_io_t::writeconv.
*/
int writeconv_pre_ecflags;
/**
* Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
* ::rb_io_t::writeconv.
*/
VALUE writeconv_pre_ecopts;
/**
* This is a Ruby level mutex. It avoids multiple threads to write to an
* IO at once; helps for instance rb_io_puts() to ensure newlines right
* next to its arguments.
*
* This of course doesn't help inter-process IO interleaves, though.
*/
VALUE write_lock;
/**
* The timeout associated with this IO when performing blocking operations.
*/
VALUE timeout;
} rb_io_t;
/** @alias{rb_io_enc_t} */
typedef struct rb_io_enc_t rb_io_enc_t;
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_IO_T 1
/**
* @name Possible flags for ::rb_io_t::mode
*
* @{
*/
/** The IO is opened for reading. */
#define FMODE_READABLE 0x00000001
/** The IO is opened for writing. */
#define FMODE_WRITABLE 0x00000002
/** The IO is opened for both read/write. */
#define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE)
/**
* The IO is in "binary mode". This is not what everything rb_io_binmode()
* concerns. This low-level flag is to stop CR <-> CRLF conversions that would
* happen in the underlying operating system.
*
* Setting this one and #FMODE_TEXTMODE at the same time is a contradiction.
* Setting this one and #ECONV_NEWLINE_DECORATOR_MASK at the same time is also
* a contradiction.
*/
#define FMODE_BINMODE 0x00000004
/**
* The IO is in "sync mode". All output is immediately flushed to the
* underlying operating system then. Can be set via rb_io_synchronized(), but
* there is no way except calling `IO#sync=` to reset.
*/
#define FMODE_SYNC 0x00000008
/**
* The IO is a TTY. What is a TTY and what isn't depends on the underlying
* operating system's `isatty(3)` output. You cannot change this.
*/
#define FMODE_TTY 0x00000010
/**
* Ruby eventually detects that the IO is bidirectional. For instance a TTY
* has such property. There are several other things known to be duplexed.
* Additionally you (extension library authors) can also implement your own
* bidirectional IO subclasses. One of such example is `Socket`.
*/
#define FMODE_DUPLEX 0x00000020
/**
* The IO is opened for appending. This mode always writes at the end of the
* IO. Ruby manages this flag for record but basically the logic behind this
* mode is at the underlying operating system. We almost do nothing.
*/
#define FMODE_APPEND 0x00000040
/**
* The IO is opened for creating. This makes sense only when the destination
* file does not exist at the time the IO object was created. This is the
* default mode for writing, but you can pass `"r+"` to `IO.open` etc., to
* reroute this creation.
*/
#define FMODE_CREATE 0x00000080
/* #define FMODE_NOREVLOOKUP 0x00000100 */
/**
* This flag amends the effect of #FMODE_CREATE, so that if there already is a
* file at the given path the operation fails. Using this you can be sure that
* the file you get is a fresh new one.
*/
#define FMODE_EXCL 0x00000400
/**
* This flag amends the effect of #FMODE_CREATE, so that if there already is a
* file at the given path it gets truncated.
*/
#define FMODE_TRUNC 0x00000800
/**
* The IO is in "text mode". On systems where such mode make sense, this flag
* changes the way the IO handles the contents. On POSIX systems it is
* basically a no-op, but with this flag set you can optionally let Ruby
* manually convert newlines, unlike when in binary mode:
*
* ```ruby
* IO.open("/p/a/t/h", "wt", crlf_newline: true) # "wb" is NG.
* ```
*
* Setting this one and #FMODE_BINMODE at the same time is a contradiction.
*/
#define FMODE_TEXTMODE 0x00001000
/* #define FMODE_PREP 0x00010000 */
/* #define FMODE_SIGNAL_ON_EPIPE 0x00020000 */
/**
* This flag amends the encoding of the IO so that the BOM of the contents of
* the IO takes effect.
*/
#define FMODE_SETENC_BY_BOM 0x00100000
/* #define FMODE_UNIX 0x00200000 */
/* #define FMODE_INET 0x00400000 */
/* #define FMODE_INET6 0x00800000 */
/** @} */
/**
* Queries the underlying IO pointer.
*
* @param[in] obj An IO object.
* @param[out] fp A variable of type ::rb_io_t.
* @exception rb_eFrozenError `obj` is frozen.
* @exception rb_eIOError `obj` is closed.
* @post `fp` holds `obj`'s underlying IO.
*/
#define RB_IO_POINTER(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
/**
* This is an old name of #RB_IO_POINTER. Not sure if we want to deprecate
* this macro. There still are tons of usages out there in the wild.
*/
#define GetOpenFile RB_IO_POINTER
/**
* Fills an IO object. This makes the best sense when called from inside of an
* `#initialize` method of a 3rd party extension library that inherits
* ::rb_cIO.
*
* If the passed IO is already opened for something it first closes that and
* opens a new one instead.
*
* @param[out] obj An IO object to fill in.
* @param[out] fp A variable of type ::rb_io_t.
* @exception rb_eTypeError `obj` is not ::RUBY_T_FILE.
* @post `fp` holds `obj`'s underlying IO.
*/
#define RB_IO_OPEN(obj, fp) do {\
(fp) = rb_io_make_open_file(obj);\
} while (0)
/**
* This is an old name of #RB_IO_OPEN. Not sure if we want to deprecate this
* macro. There still are usages out there in the wild.
*/
#define MakeOpenFile RB_IO_OPEN
/**
* @private
*
* This is an implementation detail of #RB_IO_OPEN. People don't use it
* directly.
*
* @param[out] obj An IO object to fill in.
* @exception rb_eTypeError `obj` is not ::RUBY_T_FILE.
* @return `obj`'s backend IO.
* @post `obj` is initialised.
*/
rb_io_t *rb_io_make_open_file(VALUE obj);
/**
* Finds or creates a stdio's file structure from a Ruby's one. This can be
* handy if you want to call an external API that accepts `FILE *`.
*
* @note Note however, that `FILE`s can have their own buffer. Mixing Ruby's
* and stdio's file are basically dangerous. Use with care.
*
* @param[in,out] fptr Target IO.
* @return A stdio's file, created if absent.
* @post `fptr` has its corresponding stdio's file.
*
* @internal
*
* We had rich support for `FILE` before! In the days of 1.8.x ::rb_io_t was
* like this:
*
* ```CXX
* typedef struct rb_io_t {
* FILE *f; // stdio ptr for read/write
* FILE *f2; // additional ptr for rw pipes
* int mode; // mode flags
* int pid; // child's pid (for pipes)
* int lineno; // number of lines read
* char *path; // pathname for file
* void (*finalize) _((struct rb_io_t*,int)); // finalize proc
* } rb_io_t;
*```
*
* But we eventually abandoned this layout. It was too difficult. We could
* not have fine-grained control over the `f` field.
*
* - `FILE` tends to be an opaque struct. It does not interface well with
* `select(2)` etc. This makes IO multiplexing quite hard. Using stdio,
* there is arguably no portable way to know if `fwrite(3)` blocks.
*
* - Nonblocking mode, which is another core concept that enables IO
* multiplexing, does not interface with stdio routines at all.
*
* - Detection of duplexed IO is also hard for the same reason.
*
* - `feof(3)` is not portable.
* https://mail.python.org/pipermail/python-dev/2001-January/011390.html
*
* - Solaris was a thing back then. They could not have more than 256 `FILE`
* structures at a time. Their file descriptors ware stored in an
* `unsigned char`.
*
* - It is next to impossible to avoid SEGV, especially when a thread tries to
* `ungetc(3)`-ing from a `FILE` which is `fread(3)`-ed by another one.
*
* In short, it is a bad idea to let someone else manage IO buffers, especially
* someone you cannot control. This still applies to extension libraries
* methinks. Ruby doesn't prevent you from shooting yourself in the foot, but
* consider yourself warned here.
*/
FILE *rb_io_stdio_file(rb_io_t *fptr);
/**
* Identical to rb_io_stdio_file(), except it takes file descriptors instead of
* Ruby's IO. It can also be seen as a compatibility layer to wrap
* `fdopen(3)`. Nowadays all supporting systems, including Windows, have
* `fdopen`. Why not use them.
*
* @param[in] fd A file descriptor.
* @param[in] modestr C string, something like `"r+"`.
* @exception rb_eSystemCallError `fdopen` failed for some reason.
* @return A stdio's file associated with `fd`.
* @note Interpretation of `modestr` depends on the underlying operating
* system. On glibc you might be able to pass e.g. `"rm"`, but
* that's an extension to POSIX.
*/
FILE *rb_fdopen(int fd, const char *modestr);
/**
* Maps a file mode string (that rb_file_open() takes) into a mixture of
* `FMODE_` flags. This for instance returns
* `FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE | FMODE_EXCL` for `"wx"`.
*
* @note You cannot pass this return value to OS provided `open(2)` etc.
*
* @param[in] modestr File mode, in C's string.
* @exception rb_eArgError `modestr` is broken.
* @return A set of flags.
*
* @internal
*
* rb_io_modestr_fmode() is not a pure function because it raises.
*/
int rb_io_modestr_fmode(const char *modestr);
/**
* Identical to rb_io_modestr_fmode(), except it returns a mixture of `O_`
* flags. This for instance returns `O_WRONLY | O_TRUNC | O_CREAT | O_EXCL` for
* `"wx"`.
*
* @param[in] modestr File mode, in C's string.
* @exception rb_eArgError `modestr` is broken.
* @return A set of flags.
*
* @internal
*
* rb_io_modestr_oflags() is not a pure function because it raises.
*/
int rb_io_modestr_oflags(const char *modestr);
RBIMPL_ATTR_CONST()
/**
* Converts an oflags (that rb_io_modestr_oflags() returns) to a fmode (that
* rb_io_mode_flags() returns). This is a purely functional operation.
*
* @param[in] oflags A set of `O_` flags.
* @return Corresponding set of `FMODE_` flags.
*/
int rb_io_oflags_fmode(int oflags);
/**
* Asserts that an IO is opened for writing.
*
* @param[in] fptr An IO you want to write to.
* @exception rb_eIOError `fptr` is not for writing.
* @post Upon successful return `fptr` is ready for writing.
*
* @internal
*
* The parameter must have been `const rb_io_t *`.
*/
void rb_io_check_writable(rb_io_t *fptr);
/** @alias{rb_io_check_byte_readable} */
void rb_io_check_readable(rb_io_t *fptr);
/**
* Asserts that an IO is opened for character-based reading. A character can
* be wider than a byte. Because of this we have to buffer reads from
* descriptors. This fiction checks if that is possible.
*
* @param[in] fptr An IO you want to read characters from.
* @exception rb_eIOError `fptr` is not for reading.
* @post Upon successful return `fptr` is ready for reading characters.
*
* @internal
*
* Unlike rb_io_check_writable() the parameter cannot be `const rb_io_t *`.
* Behind the scene this operation flushes its write buffers. This is because
* of OpenSSL. They mandate this way.
*
* @see "Can I use OpenSSL's SSL library with non-blocking I/O?"
* https://www.openssl.org/docs/faq.html
*/
void rb_io_check_char_readable(rb_io_t *fptr);
/**
* Asserts that an IO is opened for byte-based reading. Byte-based and
* character-based reading operations cannot be mixed at a time.
*
* @param[in] fptr An IO you want to read characters from.
* @exception rb_eIOError `fptr` is not for reading.
* @post Upon successful return `fptr` is ready for reading bytes.
*/
void rb_io_check_byte_readable(rb_io_t *fptr);
/**
* Destroys the given IO. Any pending operations are flushed.
*
* @note It makes no sense to call this function from anywhere outside of your
* class' ::rb_data_type_struct::dfree.
*
* @param[out] fptr IO to close.
* @post `fptr` is no longer a valid pointer.
*/
int rb_io_fptr_finalize(rb_io_t *fptr);
/**
* Sets #FMODE_SYNC.
*
* @note There is no way for C extensions to undo this operation.
*
* @param[out] fptr IO to set the flag.
* @exception rb_eIOError `fptr` is not opened.
* @post `fptr` is in sync mode.
*/
void rb_io_synchronized(rb_io_t *fptr);
/**
* Asserts that the passed IO is initialised.
*
* @param[in] fptr IO that you expect be initialised.
* @exception rb_eIOError `fptr` is not initialised.
* @post `fptr` is initialised.
*/
void rb_io_check_initialized(rb_io_t *fptr);
/**
* This badly named function asserts that the passed IO is _open_.
*
* @param[in] fptr An IO
* @exception rb_eIOError `fptr` is closed.
* @post `fptr` is open.
*/
void rb_io_check_closed(rb_io_t *fptr);
/**
* Identical to rb_io_check_io(), except it raises exceptions on conversion
* failures.
*
* @param[in] io Target object.
* @exception rb_eTypeError No implicit conversion to IO.
* @return Return value of `obj.to_io`.
* @see rb_str_to_str
* @see rb_ary_to_ary
*/
VALUE rb_io_get_io(VALUE io);
/**
* Try converting an object to its IO representation using its `to_io` method,
* if any. If there is no such thing, returns ::RUBY_Qnil.
*
* @param[in] io Arbitrary ruby object to convert.
* @exception rb_eTypeError `obj.to_io` returned something non-IO.
* @retval RUBY_Qnil No conversion from `obj` to IO defined.
* @retval otherwise Converted IO representation of `obj`.
* @see rb_check_array_type
* @see rb_check_string_type
* @see rb_check_hash_type
*/
VALUE rb_io_check_io(VALUE io);
/**
* Queries the tied IO for writing. An IO can be duplexed. Fine. The thing
* is, that characteristics could sometimes be achieved by the underlying
* operating system (for instance a socket's duplexity is by nature) but
* sometimes by us. Notable example is a bidirectional pipe. Suppose you
* have:
*
* ```ruby
* fp = IO.popen("-", "r+")
* ```
*
* This pipe is duplexed (the `"r+"`). You can both read from/write to it.
* However your operating system may or may not implement bidirectional pipes.
* FreeBSD is one of such operating systems known to have one; OTOH Linux is
* known to lack such things. So to achieve maximum portability, Ruby's
* bidirectional pipes are done purely in user land. A pipe in ruby can have
* multiple file descriptors; one for reading and the other for writing. This
* API is to obtain the IO port which corresponds to the passed one, for
* writing.
*
* @param[in] io An IO.
* @return Its tied IO for writing, if any, or `io` itself otherwise.
*/
VALUE rb_io_get_write_io(VALUE io);
/**
* Assigns the tied IO for writing. See rb_io_get_write_io() for what a "tied
* IO for writing" is.
*
* @param[out] io An IO.
* @param[in] w Another IO.
* @retval RUBY_Qnil There was no tied IO for writing for `io`.
* @retval otherwise The IO formerly tied to `io`.
* @post `io` ties `w` for writing.
*
* @internal
*
* @shyouhei doesn't think there is any needs of this function for 3rd party
* extension libraries.
*/
VALUE rb_io_set_write_io(VALUE io, VALUE w);
/**
* Instructs the OS to put its internal file structure into "nonblocking mode".
* This is an in-Kernel concept. Reading from/writing to that file using C
* function calls would return -1 with errno set. However when it comes to a
* ruby program, we hide that error behind our `IO#read` method. Ruby level
* `IO#read` blocks regardless of this flag. If you want to avoid blocking,
* you should consider using methods like `IO#readpartial`.
*
* ```ruby
* require 'io/nonblock'
* STDIN.nonblock = true
* STDIN.gets # blocks.
* ```
*
* As of writing there is a room of this API in Fiber schedulers. A Fiber
* scheduler could be written in a way its behaviour depends on this property.
* You need an in-depth understanding of how schedulers work to properly
* leverage this, though.
*
* @note Note however that nonblocking-ness propagates across process
* boundaries. You must really carefully watch your step when turning
* for instance `stderr` into nonblock mode (it tends to be shared
* across many processes). Also it is a complete disaster to mix a
* nonblocking file and stdio, and `stderr` tends to be under control of
* stdio in other processes.
*
* @param[out] fptr An IO that is to ne nonblocking.
* @post Descriptor that `fptr` describes is under nonblocking mode.
*
* @internal
*
* There is `O_NONBLOCK` but not `FMODE_NONBLOCK`. You cannot atomically
* create a nonblocking file descriptor using our API.
*/
void rb_io_set_nonblock(rb_io_t *fptr);
/**
* Returns an integer representing the numeric file descriptor for
* <em>io</em>.
*
* @param[in] io An IO.
* @retval int A file descriptor.
*/
int rb_io_descriptor(VALUE io);
/**
* This function breaks down the option hash that `IO#initialize` takes into
* components. This is an implementation detail of rb_io_extract_modeenc()
* today. People prefer that API instead.
*
* @param[in] opt The hash to decompose.
* @param[out] enc_p Return value buffer.
* @param[out] enc2_p Return value buffer.
* @param[out] fmode_p Return value buffer.
* @exception rb_eTypeError `opt` is broken.
* @exception rb_eArgError Specified encoding does not exist.
* @retval 1 Components got extracted.
* @retval 0 Otherwise.
* @post `enc_p` is the specified internal encoding.
* @post `enc2_p` is the specified external encoding.
* @post `fmode_p` is the specified set of `FMODE_` modes.
*/
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p);
/**
* This function can be seen as an extended version of
* rb_io_extract_encoding_option() that not only concerns the option hash but
* also mode string and so on. This should be mixed with rb_scan_args() like:
*
* ```CXX
* // This method mimics File.new
* static VALUE
* your_method(int argc, const VALUE *argv, VALUE self)
* {
* VALUE f; // file name
* VALUE m; // open mode
* VALUE p; // permission (O_CREAT)
* VALUE k; // keywords
* rb_io_enc_t c; // converter
* int oflags;
* int fmode;
*
* int n = rb_scan_args(argc, argv, "12:", &f, &m, &p, &k);
* rb_io_extract_modeenc(&m, &p, k, &oflags, &fmode, &c);
*
* // Every local variables declared so far has been properly filled here.
* ...
* }
* ```
*
* @param[in,out] vmode_p Pointer to a mode object.
* @param[in,out] vperm_p Pointer to a permission object.
* @param[in] opthash Keyword arguments
* @param[out] oflags_p `O_` flags return buffer.
* @param[out] fmode_p `FMODE_` flags return buffer.
* @param[out] convconfig_p Encoding config return buffer.
* @exception rb_eTypeError Unexpected object (e.g. Time) passed.
* @exception rb_eArgError Contradiction inside of params.
* @post `*vmode_p` is a mode object (filled if any).
* @post `*vperm_p` is a permission object (filled if any).
* @post `*oflags_p` is filled with `O_` flags.
* @post `*fmode_p` is filled with `FMODE_` flags.
* @post `*convconfig_p` is filled with conversion instructions.
*
* @internal
*
* ```rbs
* class File
* def initialize: (
* (String | int) path,
* ?(String | int) fmode,
* ?(String | int) perm,
* ?mode: (String | int),
* ?flags: int,
* ?external_encoding: (Encoding | String),
* ?internal_encoding: (Encoding | String),
* ?encoding: String,
* ?textmode: bool,
* ?binmode: bool,
* ?autoclose: bool,
* ?invalid: :replace,
* ?undef: :replace,
* ?replace: String,
* ?fallback: (Hash | Proc | Method),
* ?xml: (:text | :attr),
* ?crlf_newline: bool,
* ?cr_newline: bool,
* ?universal_newline: bool
* ) -> void
* ```
*/
void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, rb_io_enc_t *convconfig_p);
/* :TODO: can this function be __attribute__((warn_unused_result)) or not? */
/**
* Buffered write to the passed IO.
*
* @param[out] io Destination IO.
* @param[in] buf Contents to go to `io`.
* @param[in] size Number of bytes of `buf`.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eIOError `io` is not open for writing.
* @exception rb_eSystemCallError `writev(2)` failed for some reason.
* @retval -1 Write failed.
* @retval otherwise Number of bytes actually written.
* @post `buf` is written to `io`.
* @note Partial write is a thing. It is a failure not to check the
* return value.
*/
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);
//RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_readable"))
/**
* Blocks until the passed file descriptor gets readable.
*
* @deprecated We now prefer rb_io_maybe_wait_readable() over this one.
* @param[in] fd The file descriptor to wait.
* @exception rb_eIOError Bad file descriptor.
* @return 0 or 1 (meaning unclear).
* @post `fd` is ready for reading.
*/
int rb_io_wait_readable(int fd);
//RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_writable"))
/**
* Blocks until the passed file descriptor gets writable.
*
* @deprecated We now prefer rb_io_maybe_wait_writable() over this one.
* @param[in] fd The file descriptor to wait.
* @exception rb_eIOError Bad file descriptor.
* @return 0 or 1 (meaning unclear).
*/
int rb_io_wait_writable(int fd);
//RBIMPL_ATTR_DEPRECATED(("use rb_io_wait"))
/**
* Blocks until the passed file descriptor is ready for the passed events.
*
* @deprecated We now prefer rb_io_maybe_wait() over this one.
* @param[in] fd The file descriptor to wait.
* @param[in] events A set of enum ::rb_io_event_t.
* @param[in,out] tv Timeout.
* @retval 0 Operation timed out.
* @retval -1 `select(2)` failed for some reason.
* @retval otherwise A set of enum ::rb_io_event_t.
* @note Depending on your operating system `tv` might or might not
* be updated (POSIX permits both). Portable programs must
* have no assumptions.
*/
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
/**
* Get the timeout associated with the specified io object.
*
* @param[in] io An IO object.
* @retval RUBY_Qnil There is no associated timeout.
* @retval Otherwise The timeout value.
*/
VALUE rb_io_timeout(VALUE io);
/**
* Set the timeout associated with the specified io object. This timeout is
* used as a best effort timeout to prevent operations from blocking forever.
*
* @param[in] io An IO object.
* @param[in] timeout A timeout value. Must respond to #to_f.
* @
*/
VALUE rb_io_set_timeout(VALUE io, VALUE timeout);
/**
* Blocks until the passed IO is ready for the passed events. The "events"
* here is a Ruby level integer, which is an OR-ed value of `IO::READABLE`,
* `IO::WRITable`, and `IO::PRIORITY`.
*
* If timeout is `Qnil`, it will use the default timeout as given by
* `rb_io_timeout(io)`.
*
* @param[in] io An IO object to wait.
* @param[in] events See above.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
* If Qnil, use the default timeout. If Qfalse
* or Qundef, wait forever.
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
* @retval RUBY_Qfalse Operation timed out.
* @retval Otherwise Actual events reached.
*/
VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout);
/**
* Identical to rb_io_wait() except it additionally takes previous errno. If
* the passed errno indicates for instance `EINTR`, this function returns
* immediately. This is expected to be called in a loop.
*
* ```CXX
* while (true) {
*
* ... // Your interesting operation here
* // `errno` could be updated
*
* rb_io_maybe_wait(errno, io, ev, Qnil);
* }
* ```
*
* @param[in] error System errno.
* @param[in] io An IO object to wait.
* @param[in] events An integer set of interests.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
* @retval RUBY_Qfalse Operation timed out.
* @retval Otherwise Actual events reached.
*
* @internal
*
* This function to return ::RUBY_Qfalse on timeout could be unintended. It
* seems timeout feature has some rough edge.
*/
VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout);
/**
* Blocks until the passed IO is ready for reading, if that makes sense for the
* passed errno. This is a special case of rb_io_maybe_wait() that only
* concerns for reading.
*
* @param[in] error System errno.
* @param[in] io An IO object to wait.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
* @retval 0 Operation timed out.
* @retval Otherwise Always returns ::RUBY_IO_READABLE.
*/
int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
/**
* Blocks until the passed IO is ready for writing, if that makes sense for the
* passed errno. This is a special case of rb_io_maybe_wait() that only
* concernsfor writing.
*
* @param[in] error System errno.
* @param[in] io An IO object to wait.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
* @retval 0 Operation timed out.
* @retval Otherwise Always returns ::RUBY_IO_WRITABLE.
*/
int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout);
/** @cond INTERNAL_MACRO */
/* compatibility for ruby 1.8 and older */
#define rb_io_mode_flags(modestr) [<"rb_io_mode_flags() is obsolete; use rb_io_modestr_fmode()">]
#define rb_io_modenum_flags(oflags) [<"rb_io_modenum_flags() is obsolete; use rb_io_oflags_fmode()">]
/** @endcond */
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
* @exception rb_eFrozenError obj is frozen.
* @return The passed `obj`
*/
VALUE rb_io_taint_check(VALUE obj);
RBIMPL_ATTR_NORETURN()
/**
* Utility function to raise ::rb_eEOFError.
*
* @exception rb_eEOFError End of file situation.
* @note It never returns.
*/
void rb_eof_error(void);
/**
* Blocks until there is a pending read in the passed IO. If there already is
* it just returns.
*
* @param[out] fptr An IO to wait for reading.
* @post The are bytes to be read.
*/
void rb_io_read_check(rb_io_t *fptr);
RBIMPL_ATTR_PURE()
/**
* Queries if the passed IO has any pending reads. Unlike rb_io_read_check()
* this doesn't block; has no side effects.
*
* @param[in] fptr An IO which can have pending reads.
* @retval 0 The IO is empty.
* @retval 1 There is something buffered.
*/
int rb_io_read_pending(rb_io_t *fptr);
/**
* Constructs an instance of ::rb_cStat from the passed information.
*
* @param[in] st A stat.
* @return Allocated new instance of ::rb_cStat.
*/
VALUE rb_stat_new(const struct stat *st);
/* gc.c */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_IO_H */
include/ruby/subst.h 0000644 00000001446 15040330602 0010457 0 ustar 00 #ifndef RUBY_SUBST_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_SUBST_H 1
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#undef snprintf
#undef vsnprintf
#define snprintf ruby_snprintf
#define vsnprintf ruby_vsnprintf
#ifdef BROKEN_CLOSE
#undef getpeername
#define getpeername ruby_getpeername
#undef getsockname
#define getsockname ruby_getsockname
#undef shutdown
#define shutdown ruby_shutdown
#undef close
#define close ruby_close
#endif
#endif
include/ruby/debug.h 0000644 00000055137 15040330602 0010413 0 ustar 00 #ifndef RB_DEBUG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RB_DEBUG_H 1
/**
* @file
* @author $Author: ko1 $
* @date Tue Nov 20 20:35:08 2012
* @copyright Copyright (C) 2012 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/event.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* Note: This file contains experimental APIs. */
/* APIs can be replaced at Ruby 2.0.1 or later */
/**
* @name Frame-profiling APIs
*
* @{
*/
RBIMPL_ATTR_NONNULL((3))
/**
* Queries mysterious "frame"s of the given range.
*
* The returned values are opaque backtrace pointers, which you are allowed to
* issue a very limited set of operations listed below. Don't call arbitrary
* ruby methods.
*
* @param[in] start Start position (0 means the topmost).
* @param[in] limit Number objects of `buff`.
* @param[out] buff Return buffer.
* @param[out] lines Return buffer.
* @return Number of objects filled into `buff`.
* @post `buff` is filled with backtrace pointers.
* @post `lines` is filled with `__LINE__` of each backtraces.
*
* @internal
*
* @shyouhei doesn't like this abuse of ::VALUE. It should have been
* `const struct rb_callable_method_entry_struct *`.
*/
int rb_profile_frames(int start, int limit, VALUE *buff, int *lines);
/**
* Queries the path of the passed backtrace.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil The frame is implemented in C etc.
* @retval otherwise Where `frame` is running.
*/
VALUE rb_profile_frame_path(VALUE frame);
/**
* Identical to rb_profile_frame_path(), except it tries to expand the
* returning path. In case the path is `require`-d from something else
* rb_profile_frame_path() can return relative paths. This one tries to avoid
* that.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval "<cfunc>" The frame is in C.
* @retval RUBY_Qnil Can't infer real path (inside of `eval` etc.).
* @retval otherwise Where `frame` is running.
*/
VALUE rb_profile_frame_absolute_path(VALUE frame);
/**
* Queries human-readable "label" string. This is `"<main>"` for the toplevel,
* `"<compiled>"` for evaluated ones, method name for methods, class name for
* classes.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil Can't infer the label (C etc.).
* @retval "<main>" The frame is global toplevel.
* @retval "<compiled>" The frame is dynamic.
* @retval otherwise Label of the frame.
*/
VALUE rb_profile_frame_label(VALUE frame);
/**
* Identical to rb_profile_frame_label(), except it does not "qualify" the
* result. Consider the following backtrace:
*
* ```ruby
* def bar
* caller_locations
* end
*
* def foo
* [1].map { bar }.first
* end
*
* obj = foo.first
* obj.label # => "block in foo"
* obj.base_label # => "foo"
* ```
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil Can't infer the label (C etc.).
* @retval "<main>" The frame is global toplevel.
* @retval "<compiled>" The frame is dynamic.
* @retval otherwise Base label of the frame.
*/
VALUE rb_profile_frame_base_label(VALUE frame);
/**
* Identical to rb_profile_frame_label(), except it returns a qualified result.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil Can't infer the label (C etc.).
* @retval "<main>" The frame is global toplevel.
* @retval "<compiled>" The frame is dynamic.
* @retval otherwise Qualified label of the frame.
*
* @internal
*
* As of writing there is no way to obtain this return value from a Ruby
* script. This may change in future (it took 8 years and still no progress,
* though).
*/
VALUE rb_profile_frame_full_label(VALUE frame);
/**
* Queries the first line of the method of the passed frame pointer. Can be
* handy when for instance a debugger want to display the frame in question.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil Can't infer the line (C etc.).
* @retval otherwise Line number of the method in question.
*/
VALUE rb_profile_frame_first_lineno(VALUE frame);
/**
* Queries the class path of the method that the passed frame represents.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil Can't infer the class (global toplevel etc.).
* @retval otherwise Class path as in rb_class_path().
*/
VALUE rb_profile_frame_classpath(VALUE frame);
/**
* Queries if the method of the passed frame is a singleton class.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qtrue It is a singleton method.
* @retval RUBY_Qfalse Otherwise (normal method/non-method).
*/
VALUE rb_profile_frame_singleton_method_p(VALUE frame);
/**
* Queries the name of the method of the passed frame.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil The frame in question is not a method.
* @retval otherwise Name of the method of the frame.
*/
VALUE rb_profile_frame_method_name(VALUE frame);
/**
* Identical to rb_profile_frame_method_name(), except it "qualifies" the
* return value with its defining class.
*
* @param[in] frame What rb_profile_frames() returned.
* @retval RUBY_Qnil The frame in question is not a method.
* @retval otherwise Qualified name of the method of the frame.
*/
VALUE rb_profile_frame_qualified_method_name(VALUE frame);
/** @} */
/**
* @name Debug inspector APIs
*
* @{
*/
/** Opaque struct representing a debug inspector. */
typedef struct rb_debug_inspector_struct rb_debug_inspector_t;
/**
* Type of the callback function passed to rb_debug_inspector_open().
* Inspection shall happen only inside of them. The passed pointers gets
* invalidated once after the callback returns.
*
* @param[in] dc A debug context.
* @param[in,out] data What was passed to rb_debug_inspector_open().
* @return What would be the return value of rb_debug_inspector_open().
*/
typedef VALUE (*rb_debug_inspector_func_t)(const rb_debug_inspector_t *dc, void *data);
/**
* Prepares, executes, then cleans up a debug session.
*
* @param[in] func A callback to run inside of a debug session.
* @param[in,out] data Passed as-is to `func`.
* @return What was returned from `func`.
*/
VALUE rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data);
/**
* Queries the backtrace object of the context. This is as if you call
* `caller_locations` at the point of debugger.
*
* @param[in] dc A debug context.
* @return An array of `Thread::Backtrace::Location` which represents the
* current point of execution at `dc`.
*/
VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc);
/**
* Queries the current receiver of the passed context's upper frame.
*
* @param[in] dc A debug context.
* @param[in] index Index of the frame from top to bottom.
* @exception rb_eArgError `index` out of range.
* @return The current receiver at `index`-th frame.
*/
VALUE rb_debug_inspector_frame_self_get(const rb_debug_inspector_t *dc, long index);
/**
* Queries the current class of the passed context's upper frame.
*
* @param[in] dc A debug context.
* @param[in] index Index of the frame from top to bottom.
* @exception rb_eArgError `index` out of range.
* @return The current class at `index`-th frame.
*/
VALUE rb_debug_inspector_frame_class_get(const rb_debug_inspector_t *dc, long index);
/**
* Queries the binding of the passed context's upper frame.
*
* @param[in] dc A debug context.
* @param[in] index Index of the frame from top to bottom.
* @exception rb_eArgError `index` out of range.
* @return The binding at `index`-th frame.
*/
VALUE rb_debug_inspector_frame_binding_get(const rb_debug_inspector_t *dc, long index);
/**
* Queries the instruction sequence of the passed context's upper frame.
*
* @param[in] dc A debug context.
* @param[in] index Index of the frame from top to bottom.
* @exception rb_eArgError `index` out of range.
* @retval RUBY_Qnil `index`-th frame is not in Ruby (C etc.).
* @retval otherwise An instance of `RubyVM::InstructionSequence` which
* represents the instruction sequence at `index`-th
* frame.
*/
VALUE rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index);
/**
* Queries the depth of the passed context's upper frame.
*
* Note that the depth is not same as the frame index because debug_inspector
* skips some special frames but the depth counts all frames.
*
* @param[in] dc A debug context.
* @param[in] index Index of the frame from top to bottom.
* @exception rb_eArgError `index` out of range.
* @retval The depth at `index`-th frame in Integer.
*/
VALUE rb_debug_inspector_frame_depth(const rb_debug_inspector_t *dc, long index);
// A macro to recognize `rb_debug_inspector_frame_depth()` is available or not
#define RB_DEBUG_INSPECTOR_FRAME_DEPTH(dc, index) rb_debug_inspector_frame_depth(dc, index)
/**
* Return current frmae depth.
*
* @retval The depth of the current frame in Integer.
*/
VALUE rb_debug_inspector_current_depth(void);
/** @} */
/**
* @name Old style set_trace_func APIs
*
* @{
*/
/* duplicated def of include/ruby/ruby.h */
#include "ruby/internal/event.h"
/**
* Identical to rb_remove_event_hook(), except it additionally takes the data
* argument. This extra argument is the same as that of rb_add_event_hook(),
* and this function removes the hook which matches both arguments at once.
*
* @param[in] func A callback.
* @param[in] data What to be passed to `func`.
* @return Number of deleted event hooks.
* @note As multiple events can share the same `func` it is quite
* possible for the return value to become more than one.
*/
int rb_remove_event_hook_with_data(rb_event_hook_func_t func, VALUE data);
/**
* Identical to rb_add_event_hook(), except its effect is limited to the passed
* thread. Other threads are not affected by this.
*
* @param[in] thval An instance of ::rb_cThread.
* @param[in] func A callback.
* @param[in] events A set of events that `func` should run.
* @param[in] data Passed as-is to `func`.
* @exception rb_eTypeError `thval` is not a thread.
*/
void rb_thread_add_event_hook(VALUE thval, rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
/**
* Identical to rb_remove_event_hook(), except it additionally takes a thread
* argument. This extra argument is the same as that of
* rb_thread_add_event_hook(), and this function removes the hook which matches
* both arguments at once.
*
* @param[in] thval An instance of ::rb_cThread.
* @param[in] func A callback.
* @exception rb_eTypeError `thval` is not a thread.
* @return Number of deleted event hooks.
* @note As multiple events can share the same `func` it is quite
* possible for the return value to become more than one.
*/
int rb_thread_remove_event_hook(VALUE thval, rb_event_hook_func_t func);
/**
* Identical to rb_thread_remove_event_hook(), except it additionally takes the
* data argument. It can also be seen as a routine identical to
* rb_remove_event_hook_with_data(), except it additionally takes the thread.
* This function deletes hooks that satisfy all three criteria.
*
* @param[in] thval An instance of ::rb_cThread.
* @param[in] func A callback.
* @param[in] data What to be passed to `func`.
* @exception rb_eTypeError `thval` is not a thread.
* @return Number of deleted event hooks.
* @note As multiple events can share the same `func` it is quite
* possible for the return value to become more than one.
*/
int rb_thread_remove_event_hook_with_data(VALUE thval, rb_event_hook_func_t func, VALUE data);
/** @} */
/**
* @name TracePoint APIs
*
* @{
*/
/**
* Creates a tracepoint by registering a callback function for one or more
* tracepoint events. Once the tracepoint is created, you can use
* rb_tracepoint_enable to enable the tracepoint.
*
* @param[in] target_thread_not_supported_yet Meant for picking the
* thread in which the tracepoint is to be created.
* However, current implementation ignore this
* parameter, tracepoint is created for all threads.
* Simply specify Qnil.
* @param[in] events Event(s) to listen to.
* @param[in] func A callback function.
* @param[in,out] data Void pointer that will be passed to the callback
* function.
*
* When the callback function is called, it will be passed 2 parameters:
* 1. `VALUE tpval` - the TracePoint object from which trace args can be
* extracted.
* 1. `void *data` - A void pointer which helps to share scope with the
* callback function.
*
* It is important to note that you cannot register callbacks for normal events
* and internal events simultaneously because they are different purpose. You
* can use any Ruby APIs (calling methods and so on) on normal event hooks.
* However, in internal events, you can not use any Ruby APIs (even object
* creations). This is why we can't specify internal events by TracePoint
* directly. Limitations are MRI version specific.
*
* Example:
*
* ```CXX
* rb_tracepoint_new(
* Qnil,
* RUBY_INTERNAL_EVENT_NEWOBJ | RUBY_INTERNAL_EVENT_FREEOBJ,
* obj_event_i,
* data);
* ```
*
* In this example, a callback function `obj_event_i` will be registered for
* internal events #RUBY_INTERNAL_EVENT_NEWOBJ and
* #RUBY_INTERNAL_EVENT_FREEOBJ.
*/
VALUE rb_tracepoint_new(VALUE target_thread_not_supported_yet, rb_event_flag_t events, void (*func)(VALUE, void *), void *data);
/**
* Starts (enables) trace(s) defined by the passed object. A TracePoint object
* does not immediately take effect on creation. You have to explicitly call
* this API.
*
* @param[in] tpval An instance of TracePoint.
* @exception rb_eArgError A trace is already running.
* @return Undefined value. Forget this. It should have returned `void`.
* @post Trace(s) defined by `tpval` start.
*/
VALUE rb_tracepoint_enable(VALUE tpval);
/**
* Stops (disables) an already running instance of TracePoint.
*
* @param[in] tpval An instance of TracePoint.
* @return Undefined value. Forget this. It should have returned `void`.
* @post Trace(s) defined by `tpval` stop.
*/
VALUE rb_tracepoint_disable(VALUE tpval);
/**
* Queries if the passed TracePoint is up and running.
*
* @param[in] tpval An instance of TracePoint.
* @retval RUBY_Qtrue It is.
* @retval RUBY_Qfalse It isn't.
*/
VALUE rb_tracepoint_enabled_p(VALUE tpval);
/**
* Type that represents a specific trace event. Roughly resembles the
* tracepoint object that is passed to the block of `TracePoint.new`:
*
* ```ruby
* TracePoint.new(*events) do |obj|
* ... # ^^^^^ Resembles this object.
* end
* ```
*/
typedef struct rb_trace_arg_struct rb_trace_arg_t;
RBIMPL_ATTR_RETURNS_NONNULL()
/**
* Queries the current event of the passed tracepoint.
*
* @param[in] tpval An instance of TracePoint.
* @exception rb_eRuntimeError `tpval` is disabled.
* @return The current event.
*
* @internal
*
* `tpval` is a fake. There is only one instance of ::rb_trace_arg_t at one
* time. This function just returns that global variable.
*/
rb_trace_arg_t *rb_tracearg_from_tracepoint(VALUE tpval);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the event of the passed trace.
*
* @param[in] trace_arg A trace instance.
* @return Its event.
*/
rb_event_flag_t rb_tracearg_event_flag(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_tracearg_event_flag(), except it returns the name of the
* event in Ruby's symbol.
*
* @param[in] trace_arg A trace instance.
* @return Its event, in Ruby level Symbol object.
*/
VALUE rb_tracearg_event(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the line of the point where the trace is at.
*
* @param[in] trace_arg A trace instance.
* @retval 0 The trace is not at Ruby frame.
* @return otherwise Its line number.
*/
VALUE rb_tracearg_lineno(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the file name of the point where the trace is at.
*
* @param[in] trace_arg A trace instance.
* @retval RUBY_Qnil The trace is not at Ruby frame.
* @retval otherwise Its path.
*/
VALUE rb_tracearg_path(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the method name of the point where the trace is at.
*
* @param[in] trace_arg A trace instance.
* @retval RUBY_Qnil There is no method.
* @retval otherwise Its method name, in Ruby level Symbol.
*/
VALUE rb_tracearg_method_id(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_tracearg_method_id(), except it returns callee id like
* rb_frame_callee().
*
* @param[in] trace_arg A trace instance.
* @retval RUBY_Qnil There is no method.
* @retval otherwise Its method name, in Ruby level Symbol.
*/
VALUE rb_tracearg_callee_id(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the class that defines the method that the passed trace is at. This
* can be different from the class of rb_tracearg_self()'s return value because
* of inheritance(s).
*
* @param[in] trace_arg A trace instance.
* @retval RUBY_Qnil There is no method.
* @retval otherwise Its method's class.
*/
VALUE rb_tracearg_defined_class(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Creates a binding object of the point where the trace is at.
*
* @param[in] trace_arg A trace instance.
* @retval RUBY_Qnil The point has no binding.
* @retval otherwise Its binding.
*
* @internal
*
* @shyouhei has no idea on which situation shall this function return
* ::RUBY_Qnil.
*/
VALUE rb_tracearg_binding(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the receiver of the point trace is at.
*
* @param[in] trace_arg A trace instance.
* @return Its receiver.
*/
VALUE rb_tracearg_self(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the return value that the trace represents.
*
* @param[in] trace_arg A trace instance.
* @exception rb_eRuntimeError The tracing event is not return-related.
* @return The return value.
*/
VALUE rb_tracearg_return_value(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the raised exception that the trace represents.
*
* @param[in] trace_arg A trace instance.
* @exception rb_eRuntimeError The tracing event is not exception-related.
* @return The raised exception.
*/
VALUE rb_tracearg_raised_exception(rb_trace_arg_t *trace_arg);
RBIMPL_ATTR_NONNULL(())
/**
* Queries the allocated/deallocated object that the trace represents.
*
* @param[in] trace_arg A trace instance.
* @exception rb_eRuntimeError The tracing event is not GC-related.
* @return The allocated/deallocated object.
*/
VALUE rb_tracearg_object(rb_trace_arg_t *trace_arg);
/** @} */
/**
* @name Postponed Job API
*
* @{
*/
/*
* Postponed Job API
* rb_postponed_job_register and rb_postponed_job_register_one are
* async-signal-safe and used via SIGPROF by the "stackprof" RubyGem
*/
/**
* Type of postponed jobs.
*
* @param[in,out] arg What was passed to rb_postponed_job_register().
*/
typedef void (*rb_postponed_job_func_t)(void *arg);
/**
* Registers a postponed job.
*
* There are situations when running a ruby program is not possible. For
* instance when a program is in a signal handler; for another instance when
* the GC is busy. On such situations however, there might be needs to do
* something. We cannot but defer such operations until we are 100% sure it is
* safe to execute them. This mechanism is called postponed jobs. This
* function registers a new one. The registered job would eventually gets
* executed.
*
* @param[in] flags (Unused) reserved for future extensions.
* @param[in] func Job body.
* @param[in,out] data Passed as-is to `func`.
* @retval 0 Postponed job buffer is full. Failed.
* @retval otherwise Opaque return value.
* @post The passed job is postponed.
*/
int rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data);
/**
* Identical to rb_postponed_job_register_one(), except it additionally checks
* for duplicated registration. In case the passed job is already in the
* postponed job buffer this function does nothing.
*
* @param[in] flags (Unused) reserved for future extensions.
* @param[in] func Job body.
* @param[in,out] data Passed as-is to `func`.
* @retval 0 Postponed job buffer is full. Failed.
* @retval otherwise Opaque return value.
*/
int rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data);
/** @} */
/**
* @cond INTERNAL_MACRO
*
* Anything after this are intentionally left undocumented, to honour the
* comment below.
*/
/* undocumented advanced tracing APIs */
typedef enum {
RUBY_EVENT_HOOK_FLAG_SAFE = 0x01,
RUBY_EVENT_HOOK_FLAG_DELETED = 0x02,
RUBY_EVENT_HOOK_FLAG_RAW_ARG = 0x04
} rb_event_hook_flag_t;
void rb_add_event_hook2(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);
void rb_thread_add_event_hook2(VALUE thval, rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);
/** @endcond */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_DEBUG_H */
include/ruby/config.h 0000644 00000002277 15040330602 0010567 0 ustar 00 /*
* Kluge to support multilib installation of both 32- and 64-bit RPMS:
* we need to arrange that header files that appear in both RPMs are
* identical. Hence, this file is architecture-independent and calls
* in an arch-dependent file that will appear in just one RPM.
*
* To avoid breaking arches not explicitly supported by Red Hat, we
* use this indirection file *only* on known multilib arches.
*
* We pay attention to include _only_ the original multilib-unclean
* header file. Including any other system-header file could cause
* unpredictable include-ordering issues (rhbz#1412274, comment #16).
*
* Note: this may well fail if user tries to use gcc's -I- option.
* But that option is deprecated anyway.
*/
#if defined(__x86_64__)
#include "config-x86_64.h"
#elif defined(__i386__)
#include "config-i386.h"
#elif defined(__ppc64__) || defined(__powerpc64__)
#include "config-ppc64.h"
#elif defined(__ppc__) || defined(__powerpc__)
#include "config-ppc.h"
#elif defined(__s390x__)
#include "config-s390x.h"
#elif defined(__s390__)
#include "config-s390.h"
#elif defined(__sparc__) && defined(__arch64__)
#include "config-sparc64.h"
#elif defined(__sparc__)
#include "config-sparc.h"
#endif
include/ruby/st.h 0000644 00000016751 15040330602 0007752 0 ustar 00 /* This is a public domain general purpose hash table package
originally written by Peter Moore @ UCB.
The hash table data structures were redesigned and the package was
rewritten by Vladimir Makarov <vmakarov@redhat.com>. */
#ifndef RUBY_ST_H
#define RUBY_ST_H 1
#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif
#include "ruby/defines.h"
RUBY_SYMBOL_EXPORT_BEGIN
#if SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long st_data_t;
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG st_data_t;
#else
# error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
#endif
#define ST_DATA_T_DEFINED
#ifndef CHAR_BIT
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
#endif
#ifndef _
# define _(args) args
#endif
#ifndef ANYARGS
# ifdef __cplusplus
# define ANYARGS ...
# else
# define ANYARGS
# endif
#endif
typedef struct st_table st_table;
typedef st_data_t st_index_t;
/* Maximal value of unsigned integer type st_index_t. */
#define MAX_ST_INDEX_VAL (~(st_index_t) 0)
typedef int st_compare_func(st_data_t, st_data_t);
typedef st_index_t st_hash_func(st_data_t);
typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1];
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
struct st_hash_type {
int (*compare)(st_data_t, st_data_t); /* st_compare_func* */
st_index_t (*hash)(st_data_t); /* st_hash_func* */
};
#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)
#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
# define ST_DATA_COMPATIBLE_P(type) \
__builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
#else
# define ST_DATA_COMPATIBLE_P(type) 0
#endif
typedef struct st_table_entry st_table_entry;
struct st_table_entry; /* defined in st.c */
struct st_table {
/* Cached features of the table -- see st.c for more details. */
unsigned char entry_power, bin_power, size_ind;
/* How many times the table was rebuilt. */
unsigned int rebuilds_num;
const struct st_hash_type *type;
/* Number of entries currently in the table. */
st_index_t num_entries;
/* Array of bins used for access by keys. */
st_index_t *bins;
/* Start and bound index of entries in array entries.
entries_starts and entries_bound are in interval
[0,allocated_entries]. */
st_index_t entries_start, entries_bound;
/* Array of size 2^entry_power. */
st_table_entry *entries;
};
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
size_t rb_st_table_size(const struct st_table *tbl);
#define st_table_size rb_st_table_size
st_table *rb_st_init_table(const struct st_hash_type *);
#define st_init_table rb_st_init_table
st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
#define st_init_table_with_size rb_st_init_table_with_size
st_table *rb_st_init_numtable(void);
#define st_init_numtable rb_st_init_numtable
st_table *rb_st_init_numtable_with_size(st_index_t);
#define st_init_numtable_with_size rb_st_init_numtable_with_size
st_table *rb_st_init_strtable(void);
#define st_init_strtable rb_st_init_strtable
st_table *rb_st_init_strtable_with_size(st_index_t);
#define st_init_strtable_with_size rb_st_init_strtable_with_size
st_table *rb_st_init_strcasetable(void);
#define st_init_strcasetable rb_st_init_strcasetable
st_table *rb_st_init_strcasetable_with_size(st_index_t);
#define st_init_strcasetable_with_size rb_st_init_strcasetable_with_size
int rb_st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
#define st_delete rb_st_delete
int rb_st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
#define st_delete_safe rb_st_delete_safe
int rb_st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
#define st_shift rb_st_shift
int rb_st_insert(st_table *, st_data_t, st_data_t);
#define st_insert rb_st_insert
int rb_st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
#define st_insert2 rb_st_insert2
int rb_st_lookup(st_table *, st_data_t, st_data_t *);
#define st_lookup rb_st_lookup
int rb_st_get_key(st_table *, st_data_t, st_data_t *);
#define st_get_key rb_st_get_key
typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
/* *key may be altered, but must equal to the old key, i.e., the
* results of hash() are same and compare() returns 0, otherwise the
* behavior is undefined */
int rb_st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
#define st_update rb_st_update
typedef int st_foreach_callback_func(st_data_t, st_data_t, st_data_t);
typedef int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int);
int rb_st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
#define st_foreach_with_replace rb_st_foreach_with_replace
int rb_st_foreach(st_table *, st_foreach_callback_func *, st_data_t);
#define st_foreach rb_st_foreach
int rb_st_foreach_check(st_table *, st_foreach_check_callback_func *, st_data_t, st_data_t);
#define st_foreach_check rb_st_foreach_check
st_index_t rb_st_keys(st_table *table, st_data_t *keys, st_index_t size);
#define st_keys rb_st_keys
st_index_t rb_st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
#define st_keys_check rb_st_keys_check
st_index_t rb_st_values(st_table *table, st_data_t *values, st_index_t size);
#define st_values rb_st_values
st_index_t rb_st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
#define st_values_check rb_st_values_check
void rb_st_add_direct(st_table *, st_data_t, st_data_t);
#define st_add_direct rb_st_add_direct
void rb_st_free_table(st_table *);
#define st_free_table rb_st_free_table
void rb_st_cleanup_safe(st_table *, st_data_t);
#define st_cleanup_safe rb_st_cleanup_safe
void rb_st_clear(st_table *);
#define st_clear rb_st_clear
st_table *rb_st_copy(st_table *);
#define st_copy rb_st_copy
CONSTFUNC(int rb_st_numcmp(st_data_t, st_data_t));
#define st_numcmp rb_st_numcmp
CONSTFUNC(st_index_t rb_st_numhash(st_data_t));
#define st_numhash rb_st_numhash
PUREFUNC(int rb_st_locale_insensitive_strcasecmp(const char *s1, const char *s2));
#define st_locale_insensitive_strcasecmp rb_st_locale_insensitive_strcasecmp
PUREFUNC(int rb_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n));
#define st_locale_insensitive_strncasecmp rb_st_locale_insensitive_strncasecmp
#define st_strcasecmp rb_st_locale_insensitive_strcasecmp
#define st_strncasecmp rb_st_locale_insensitive_strncasecmp
PUREFUNC(size_t rb_st_memsize(const st_table *));
#define st_memsize rb_st_memsize
PUREFUNC(st_index_t rb_st_hash(const void *ptr, size_t len, st_index_t h));
#define st_hash rb_st_hash
CONSTFUNC(st_index_t rb_st_hash_uint32(st_index_t h, uint32_t i));
#define st_hash_uint32 rb_st_hash_uint32
CONSTFUNC(st_index_t rb_st_hash_uint(st_index_t h, st_index_t i));
#define st_hash_uint rb_st_hash_uint
CONSTFUNC(st_index_t rb_st_hash_end(st_index_t h));
#define st_hash_end rb_st_hash_end
CONSTFUNC(st_index_t rb_st_hash_start(st_index_t h));
#define st_hash_start(h) ((st_index_t)(h))
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE);
RUBY_SYMBOL_EXPORT_END
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
} /* extern "C" { */
#endif
#endif /* RUBY_ST_H */
include/ruby/internal/glob.h 0000644 00000011756 15040330602 0012063 0 ustar 00 #ifndef RBIMPL_GLOB_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GLOB_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Declares ::rb_glob().
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Type of a glob callback function. Called every time glob scans a path.
*
* @param[in] path The path in question.
* @param[in] arg The argument passed to rb_glob().
* @param[in] enc Encoding of the path.
* @retval -1 Not enough memory to do the operation.
* @retval 0 Operation successful.
* @retval otherwise Opaque exception state.
* @note You can use rb_protect() to generate the return value.
*
* @internal
*
* This is a wrong design. Type of `enc` should have been `rb_encoding*`
* instead of just `void*`. But we cannot change the API any longer.
*
* Though not a part of our public API, the "opaque exception state" is in fact
* an enum ruby_tag_type. You can see the potential "otherwise" values by
* looking at vm_core.h.
*/
typedef int ruby_glob_func(const char *path, VALUE arg, void *enc);
RBIMPL_ATTR_NONNULL(())
/**
* The "glob" operator. Expands the given pattern against the actual local
* filesystem, then iterates over the expanded filenames by calling the
* callback function.
*
* @param[in] pattern A glob pattern.
* @param[in] func Identical to ruby_glob_func, except it can raise
* exceptions instead of returning opaque state.
* @param[in] arg Extra argument passed to func.
* @exception rb_eException Can propagate what `func` raises.
* @note The language accepted as the pattern is not a regular
* expression. It resembles shell's glob.
*/
void rb_glob(const char *pattern, void (*func)(const char *path, VALUE arg, void *enc), VALUE arg);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_glob(), except it returns opaque exception states instead of
* raising exceptions.
*
* @param[in] pattern A glob pattern.
* @param[in] flags No, you are not allowed to use this. Just pass 0.
* @param[in] func A callback function.
* @param[in] arg Extra argument passed to func.
* @return Return value of `func`.
*
* @internal
*
* This function is completely broken by design... Not only is there no sane
* way to pass flags, but there also is no sane way to know what a return value
* is meant to be.
*
* Though not a part of our public API, and @shyouhei thinks it's a failure not
* to be a public API, the flags can be `FNM_EXTGLOB`, `FNM_DOTMATCH` etc.
* Look at dir.c for the list.
*
* Though not a part of our public API, the return value is in fact an
* enum ruby_tag_type. You can see the potential values by looking at
* vm_core.h.
*/
int ruby_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to ruby_glob(), @shyouhei currently suspects. Historically you
* had to call this function instead of ruby_glob() if the pattern included
* "{x,y,...}" syntax. However since commit 0f63d961169989a7f6dcf7c0487fe29da,
* ruby_glob() also supports that syntax. It seems as of writing these two
* functions provide basically the same functionality in a different
* implementation. Is this analysis right? Correct me! :FIXME:
*
* @param[in] pattern A glob pattern.
* @param[in] flags No, you are not allowed to use this. Just pass 0.
* @param[in] func A callback function.
* @param[in] arg Extra argument passed to func.
* @return Return value of `func`.
*/
int ruby_brace_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_GLOB_H */
include/ruby/internal/value.h 0000644 00000010410 15040330602 0012236 0 ustar 00 #ifndef RBIMPL_VALUE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VALUE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines ::VALUE and ::ID.
*/
#include "ruby/internal/static_assert.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/limits.h"
#if defined(__DOXYGEN__)
/**
* Type that represents a Ruby object. It is an unsigned integer of some kind,
* depending on platforms.
*
* ```CXX
* VALUE value = rb_eval_string("ARGF.readlines.map.with_index");
* ```
*
* @warning ::VALUE is not a pointer.
* @warning ::VALUE can be wider than `long`.
*/
typedef uintptr_t VALUE;
/**
* Type that represents a Ruby identifier such as a variable name.
*
* ```CXX
* ID method = rb_intern("method");
* VALUE result = rb_funcall(obj, method, 0);
* ```
*
* @note ::rb_cSymbol is a Ruby-level data type for the same thing.
*/
typedef uintptr_t ID;
/**
* A signed integer type that has the same width with ::VALUE.
*
* @internal
*
* @shyouhei wonders: is it guaranteed that `uintptr_t` and `intptr_t` are the
* same width? As far as I read ISO/IEC 9899:2018 section 7.20.1.4 paragraph 1
* no such description is given... or defined elsewhere?
*/
typedef intptr_t SIGNED_VALUE;
/**
* Identical to `sizeof(VALUE)`, except it is a macro that can also be used
* inside of preprocessor directives such as `#if`. Handy on occasions.
*/
#define SIZEOF_VALUE SIZEOF_UINTPTR_T
/**
* @private
*
* A compile-time constant of type ::VALUE whose value is 0.
*/
#define RBIMPL_VALUE_NULL UINTPTR_C(0)
/**
* @private
*
* A compile-time constant of type ::VALUE whose value is 1.
*/
#define RBIMPL_VALUE_ONE UINTPTR_C(1)
/**
* @private
*
* Maximum possible value that a ::VALUE can take.
*/
#define RBIMPL_VALUE_FULL UINTPTR_MAX
#elif defined HAVE_UINTPTR_T && 0
typedef uintptr_t VALUE;
typedef uintptr_t ID;
# define SIGNED_VALUE intptr_t
# define SIZEOF_VALUE SIZEOF_UINTPTR_T
# undef PRI_VALUE_PREFIX
# define RBIMPL_VALUE_NULL UINTPTR_C(0)
# define RBIMPL_VALUE_ONE UINTPTR_C(1)
# define RBIMPL_VALUE_FULL UINTPTR_MAX
#elif SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long VALUE;
typedef unsigned long ID;
# define SIGNED_VALUE long
# define SIZEOF_VALUE SIZEOF_LONG
# define PRI_VALUE_PREFIX "l"
# define RBIMPL_VALUE_NULL 0UL
# define RBIMPL_VALUE_ONE 1UL
# define RBIMPL_VALUE_FULL ULONG_MAX
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG VALUE;
typedef unsigned LONG_LONG ID;
# define SIGNED_VALUE LONG_LONG
# define LONG_LONG_VALUE 1
# define SIZEOF_VALUE SIZEOF_LONG_LONG
# define PRI_VALUE_PREFIX PRI_LL_PREFIX
# define RBIMPL_VALUE_NULL 0ULL
# define RBIMPL_VALUE_ONE 1ULL
# define RBIMPL_VALUE_FULL ULLONG_MAX
#else
# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
#endif
/** @cond INTERNAL_MACRO */
RBIMPL_STATIC_ASSERT(sizeof_int, SIZEOF_INT == sizeof(int));
RBIMPL_STATIC_ASSERT(sizeof_long, SIZEOF_LONG == sizeof(long));
RBIMPL_STATIC_ASSERT(sizeof_long_long, SIZEOF_LONG_LONG == sizeof(LONG_LONG));
RBIMPL_STATIC_ASSERT(sizeof_voidp, SIZEOF_VOIDP == sizeof(void *));
/** @endcond */
#endif /* RBIMPL_VALUE_H */
include/ruby/internal/gc.h 0000644 00000004776 15040330602 0011535 0 ustar 00 #ifndef RBIMPL_GC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Registering values to the GC.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Inform the garbage collector that the global or static variable pointed by
* `valptr` stores a live Ruby object that should not be moved. Note that
* extensions should use this API on global constants instead of assuming
* constants defined in Ruby are always alive. Ruby code can remove global
* constants.
*
* Because this registration itself has a possibility to trigger a GC, this
* function must be called before any GC-able objects is assigned to the
* address pointed by `valptr`.
*/
void rb_gc_register_address(VALUE *valptr);
/**
* An alias for `rb_gc_register_address()`.
*/
void rb_global_variable(VALUE *);
/**
* Inform the garbage collector that a pointer previously passed to
* `rb_gc_register_address()` no longer points to a live Ruby object.
*/
void rb_gc_unregister_address(VALUE *valptr);
/**
* Inform the garbage collector that `object` is a live Ruby object that should
* not be moved.
*
* See also: rb_gc_register_address()
*/
void rb_gc_register_mark_object(VALUE object);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_GC_H */
include/ruby/internal/intern/gc.h 0000644 00000037727 15040330602 0013036 0 ustar 00 #ifndef RBIMPL_INTERN_GC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_GC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_mGC.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h> /* size_t */
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* gc.c */
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
* Triggers out-of-memory error. If possible it raises ::rb_eNoMemError. But
* because we are running out of memory that is not always doable. This
* function tries hard to show something, but ultimately can die silently.
*
* @exception rb_eNoMemError Raises it if possible.
*/
void rb_memerror(void);
RBIMPL_ATTR_PURE()
/**
* Queries if the GC is busy.
*
* @retval 0 It isn't.
* @retval 1 It is.
*/
int rb_during_gc(void);
RBIMPL_ATTR_NONNULL((1))
/**
* Marks objects between the two pointers. This is one of the GC utility
* functions that you can call when you design your own
* ::rb_data_type_struct::dmark.
*
* @pre Continuous memory region from `start` to `end` shall be fully
* addressable.
* @param[out] start Pointer to an array of objects.
* @param[out] end Pointer that terminates the array of objects.
* @post Objects from `start` (included) to `end` (excluded) are marked.
*
* @internal
*
* `end` can be NULL... But that just results in no-op.
*/
void rb_gc_mark_locations(const VALUE *start, const VALUE *end);
/**
* Identical to rb_mark_hash(), except it marks only values of the table and
* leave their associated keys unmarked. This is one of the GC utility
* functions that you can call when you design your own
* ::rb_data_type_struct::dmark.
*
* @warning Of course it can break GC. Leave it unused if unsure.
* @param[in] tbl A table to mark.
* @post Values stored in `tbl` are marked.
*/
void rb_mark_tbl(struct st_table *tbl);
/**
* Identical to rb_mark_tbl(), except it marks objects using
* rb_gc_mark_movable(). This is one of the GC utility functions that you can
* call when you design your own ::rb_data_type_struct::dmark.
*
* @warning Of course it can break GC. Leave it unused if unsure.
* @param[in] tbl A table to mark.
* @post Values stored in `tbl` are marked.
*/
void rb_mark_tbl_no_pin(struct st_table *tbl);
/**
* Identical to rb_mark_hash(), except it marks only keys of the table and
* leave their associated values unmarked. This is one of the GC utility
* functions that you can call when you design your own
* ::rb_data_type_struct::dmark.
*
* @warning Of course it can break GC. Leave it unused if unsure.
* @param[in] tbl A table to mark.
* @post Keys stored in `tbl` are marked.
*/
void rb_mark_set(struct st_table *tbl);
/**
* Marks keys and values associated inside of the given table. This is one of
* the GC utility functions that you can call when you design your own
* ::rb_data_type_struct::dmark.
*
* @param[in] tbl A table to mark.
* @post Objects stored in `tbl` are marked.
*/
void rb_mark_hash(struct st_table *tbl);
/**
* Updates references inside of tables. After you marked values using
* rb_mark_tbl_no_pin(), the objects inside of the table could of course be
* moved. This function is to fixup those references. You can call this from
* your ::rb_data_type_struct::dcompact.
*
* @param[out] ptr A table that potentially includes moved references.
* @post Moved references, if any, are corrected.
*/
void rb_gc_update_tbl_refs(st_table *ptr);
/**
* Identical to rb_gc_mark(), except it allows the passed value be a
* non-object. For instance pointers to different type of memory regions are
* allowed here. Such values are silently ignored. This is one of the GC
* utility functions that you can call when you design your own
* ::rb_data_type_struct::dmark.
*
* @param[out] obj A possible object.
* @post `obj` is marked, if possible.
*/
void rb_gc_mark_maybe(VALUE obj);
/**
* Marks an object. This is one of the GC utility functions that you can call
* when you design your own ::rb_data_type_struct::dmark.
*
* @param[out] obj Arbitrary Ruby object.
* @post `obj` is marked.
*/
void rb_gc_mark(VALUE obj);
/**
* Maybe this is the only function provided for C extensions to control the
* pinning of objects, so let us describe it in detail. These days Ruby's GC
* is copying. As far as an object's physical address is guaranteed unused, it
* can move around the object space. Our GC engine rearranges these objects
* after it reclaims unreachable objects from our object space, so that the
* space is compact (improves memory locality). This is called the
* "compaction" phase, and works well most of the time... as far as there are
* no C extensions. C extensions complicate the scenario because Ruby core
* cannot detect any use of the physical address of an object inside of C
* functions. In order to prevent memory corruptions, objects observable from
* C extensions are "pinned"; they stick to where they are born until they die,
* just in case any C extensions touch their raw pointers. This variant of
* scheme is called "Mostly-Copying" garbage collector. Authors of C
* extensions, however, can extremely carefully write them to become
* compaction-aware. To do so avoid referring to a Ruby object from inside of
* your struct in the first place. But if that is not possible, use this
* function from your ::rb_data_type_struct::dmark then. This way objects
* marked using it are considered movable. If you chose this way you have to
* manually fix up locations of such moved pointers using rb_gc_location().
*
* @see Bartlett, Joel F., "Compacting Garbage Collection with Ambiguous
* Roots", ACM SIGPLAN Lisp Pointers Volume 1 Issue 6 pp. 3-12,
* April-May-June, 1988. https://doi.org/10.1145/1317224.1317225
*
* @param[in] obj Object that is movable.
* @post Values stored in `tbl` are marked.
*/
void rb_gc_mark_movable(VALUE obj);
/**
* Finds a new "location" of an object. An object can be moved on compaction.
* This function projects its new abode, or just returns the passed object if
* not moved. This is one of the GC utility functions that you can call when
* you design your own ::rb_data_type_struct::dcompact.
*
* @param[in] obj An object, possibly already moved to somewhere else.
* @return An object, which holds the current contents of former `obj`.
*/
VALUE rb_gc_location(VALUE obj);
/**
* Asserts that the passed object is no longer needed. Such objects are
* reclaimed sooner or later so this function is not mandatory. But sometimes
* you can know from your application knowledge that an object is surely dead
* at some point. Calling this as a hint can be a polite way.
*
* @param[out] obj Object, dead.
* @pre `obj` have never been passed to this function before.
* @post `obj` could be invalidated.
* @warning It is a failure to pass an object multiple times to this
* function.
* @deprecated This is now a no-op function.
*/
RBIMPL_ATTR_DEPRECATED(("this is now a no-op function"))
void rb_gc_force_recycle(VALUE obj);
/**
* Triggers a GC process. This was the only GC entry point that we had at the
* beginning. Over time our GC evolved. Now what this function does is just a
* very simplified variation of the entire GC algorithms. A series of
* procedures kicked by this API is called a "full" GC.
*
* - It immediately scans the entire object space to sort the dead.
* - It immediately reclaims any single dead bodies to reuse later.
*
* It is worth noting that the procedures above do not include evaluations of
* finalisers. They run later.
*
* @internal
*
* Finalisers are deferred until we can handle interrupts. See
* `rb_postponed_job_flush` in vm_trace.c.
*
* Of course there are GC that are not "full". For instance this one and the
* GC which runs when we are running out of memory are different. See
* `gc_profile_record_flag` defined in gc.c for the kinds of GC.
*
* In spite of the name this is not what everything that a GC can trigger. As
* of writing it seems this function does not trigger compaction. But this
* might change in future.
*/
void rb_gc(void);
/**
* Copy&paste an object's finaliser to another. This is one of the GC utility
* functions that you can call when you design your own `initialize_copy`,
* `initialize_dup`, `initialize_clone`.
*
* @param[out] dst Destination object.
* @param[in] src Source object.
* @post `dst` and `src` share the same finaliser.
*
* @internal
*
* But isn't it easier for you to call super, and let `Object#initialize_copy`
* call this function instead?
*/
void rb_gc_copy_finalizer(VALUE dst, VALUE src);
/**
* (Re-) enables GC. This makes sense only after you called rb_gc_disable().
*
* @retval RUBY_Qtrue GC was disabled before.
* @retval RUBY_Qfalse GC was enabled before.
* @post GC is enabled.
*
* @internal
*
* This is one of such exceptional functions that does not raise both Ruby
* exceptions and C++ exceptions.
*/
VALUE rb_gc_enable(void);
/**
* Disables GC. This prevents automatic GC runs when the process is running
* out of memory. Such situations shall result in rb_memerror(). However this
* does not prevent users from manually invoking rb_gc(). That should work.
* People abused this by disabling GC at the beginning of an event loop,
* process events without GC overheads, then manually force reclaiming garbage
* at the bottom of the loop. However because our GC is now much smarter than
* just calling rb_gc(), this technique is proven to be sub-optimal these days.
* It is believed that there is currently practically no needs of this
* function.
*
* @retval RUBY_Qtrue GC was disabled before.
* @retval RUBY_Qfalse GC was enabled before.
* @post GC is disabled.
*/
VALUE rb_gc_disable(void);
/**
* Identical to rb_gc(), except the return value.
*
* @return Always returns ::RUBY_Qnil.
*/
VALUE rb_gc_start(void);
/**
* Assigns a finaliser for an object. Each objects can have objects (typically
* blocks) that run immediately after that object dies. They are called
* finalisers of an object. This function associates a finaliser object with a
* target object.
*
* @note Note that finalisers run _after_ the object they finalise dies. You
* cannot for instance call its methods.
* @note If your finaliser references the object it finalises that object
* loses any chance to become a garbage; effectively leaks memory until
* the end of the process.
*
* @param[in] obj Target to finalise.
* @param[in] block Something `call`able.
* @exception rb_eRuntimeError Somehow `obj` cannot have finalisers.
* @exception rb_eFrozenError `obj` is frozen.
* @exception rb_eArgError `block` doesn't respond to `call`.
* @return The passed `block`.
* @post `block` runs after `obj` dies.
*/
VALUE rb_define_finalizer(VALUE obj, VALUE block);
/**
* Modifies the object so that it has no finalisers at all. This function is
* mainly provided for symmetry. No practical usages can be thought of.
*
* @param[out] obj Object to clear its finalisers.
* @exception rb_eFrozenError `obj` is frozen.
* @return The passed `obj`.
* @post `obj` has no finalisers.
* @note There is no way to undefine a specific part of many finalisers
* that `obj` could have. All you can do is to clear them all.
*/
VALUE rb_undefine_finalizer(VALUE obj);
/**
* Identical to rb_gc_stat(), with "count" parameter.
*
* @return Lifetime total number of runs of GC.
*/
size_t rb_gc_count(void);
/**
* Obtains various GC related profiles. The parameter can be either a Symbol
* or a Hash. If a Hash is passed, it is filled with everything currently
* available. If a Symbol is passed just that portion is returned.
*
* Possible variations of keys you can pass here change from version to
* version. You can get the list of known keys by passing an empty hash and
* let it be filled.
*
* @param[in,out] key_or_buf A Symbol, or a Hash.
* @exception rb_eTypeError Neither Symbol nor Hash.
* @exception rb_eFrozenError Frozen hash is passed.
* @return In case a Hash is passed it returns 0. Otherwise the
* profile value associated with the given key is returned.
* @post In case a Hash is passed it is filled with values.
*/
size_t rb_gc_stat(VALUE key_or_buf);
/**
* Obtains various info regarding the most recent GC run. This includes for
* instance the reason of the GC. The parameter can be either a Symbol or a
* Hash. If a Hash is passed, it is filled with everything currently
* available. If a Symbol is passed just that portion is returned.
*
* Possible variations of keys you can pass here change from version to
* version. You can get the list of known keys by passing an empty hash and
* let it be filled.
*
* @param[in,out] key_or_buf A Symbol, or a Hash.
* @exception rb_eTypeError Neither Symbol nor Hash.
* @exception rb_eFrozenError Frozen hash is passed.
* @return In case a Hash is passed it returns that hash. Otherwise
* the profile value associated with the given key is returned.
* @post In case a Hash is passed it is filled with values.
*/
VALUE rb_gc_latest_gc_info(VALUE key_or_buf);
/**
* Informs that there are external memory usages. Our GC runs when we are
* running out of memory. The amount of memory, however, can increase/decrease
* behind-the-scene. For instance DLLs can allocate memories using `mmap(2)`
* etc, which are opaque to us. Registering such external allocations using
* this function enables proper detection of how much memories an object used
* as a whole. That will trigger GCs more often than it would otherwise. You
* can also pass negative numbers here, to indicate that such external
* allocations are gone.
*
* @param[in] diff Amount of memory increased(+)/decreased(-).
*/
void rb_gc_adjust_memory_usage(ssize_t diff);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_GC_H */
include/ruby/internal/intern/proc.h 0000644 00000033044 15040330602 0013374 0 ustar 00 #ifndef RBIMPL_INTERN_PROC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PROC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cProc.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* proc.c */
/**
* Constructs a Proc object from implicitly passed components. When a ruby
* method is called with a block, that block is not explicitly passed around
* using C level function parameters. This function gathers all the necessary
* info to turn them into a Ruby level instance of ::rb_cProc.
*
* @exception rb_eArgError There is no passed block.
* @return An instance of ::rb_cProc.
*/
VALUE rb_block_proc(void);
/**
* Identical to rb_proc_new(), except it returns a lambda.
*
* @exception rb_eArgError There is no passed block.
* @return An instance of ::rb_cProc.
*/
VALUE rb_block_lambda(void);
/**
* This is an rb_iterate() + rb_block_proc() combo.
*
* ```CXX
* VALUE
* my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c))
* {
* const auto plus = rb_intern("+");
* return rb_funcall(c, plus, 1, y);
* }
*
* VALUE
* my_own_method(VALUE self)
* {
* return rb_proc_new(my_own_iterator, self);
* }
* ```
*
* @param[in] func A backend function of a proc.
* @param[in] callback_arg Passed to `func`'s callback_arg.
* @return A C-backended proc object.
*
*/
VALUE rb_proc_new(rb_block_call_func_t func, VALUE callback_arg);
/**
* Queries if the given object is a proc.
*
* @note This is about the object's data structure, not its class etc.
* @param[in] recv Object in question.
* @retval RUBY_Qtrue It is a proc.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_obj_is_proc(VALUE recv);
/**
* Evaluates the passed proc with the passed arguments.
*
* @param[in] recv The proc to call.
* @param[in] args An instance of ::RArray which is the arguments.
* @exception rb_eException Any exceptions happen inside.
* @return What the proc evaluates to.
*/
VALUE rb_proc_call(VALUE recv, VALUE args);
/**
* Identical to rb_proc_call(), except you can specify how to handle the last
* element of the given array.
*
* @param[in] recv The proc to call.
* @param[in] args An instance of ::RArray which is the arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `args`' last is not a keyword argument.
* - RB_PASS_KEYWORDS `args`' last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eException Any exceptions happen inside.
* @return What the proc evaluates to.
*/
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat);
/**
* Identical to rb_proc_call(), except you can additionally pass another proc
* object, as a block. Nowadays procs can take blocks:
*
* ```ruby
* l = -> (positional, optional=nil, *rest, kwarg:, **kwrest, &block) {
* # ... how can we pass this `&block`? ^^^^^^
* }
* ```
*
* And this function is to pass one to such procs.
*
* @param[in] recv The proc to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of proc arguments.
* @param[in] proc Proc as a passed block.
* @exception rb_eException Any exceptions happen inside.
* @return What the proc evaluates to.
*/
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc);
/**
* Identical to rb_proc_call_with_block(), except you can specify how to handle
* the last element of the given array. It can also be seen as a routine
* identical to rb_proc_call_kw(), except you can additionally pass another
* proc object as a block.
*
* @param[in] recv The proc to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of proc arguments.
* @param[in] proc Proc as a passed block.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `args`' last is not a keyword argument.
* - RB_PASS_KEYWORDS `args`' last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eException Any exceptions happen inside.
* @return What the proc evaluates to.
*/
VALUE rb_proc_call_with_block_kw(VALUE recv, int argc, const VALUE *argv, VALUE proc, int kw_splat);
/**
* Queries the number of mandatory arguments of the given Proc. If its block
* is declared to take no arguments, returns `0`. If the block is known to
* take exactly `n` arguments, returns `n`. If the block has optional
* arguments, returns `-n-1`, where `n` is the number of mandatory arguments,
* with the exception for blocks that are not lambdas and have only a finite
* number of optional arguments; in this latter case, returns `n`. Keyword
* arguments will be considered as a single additional argument, that argument
* being mandatory if any keyword argument is mandatory.
*
* @param[in] recv Target Proc object.
* @retval 0 It takes no arguments.
* @retval >0 It takes exactly this number of arguments.
* @retval <0 It takes optional arguments.
*/
int rb_proc_arity(VALUE recv);
/**
* Queries if the given object is a lambda. Instances of ::rb_cProc are either
* lambda or proc. They differ in several points. This function can
* distinguish them without actually evaluating their contents.
*
* @param[in] recv Target proc object.
* @retval RUBY_Qtrue It is a lambda.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_proc_lambda_p(VALUE recv);
/**
* Snapshots the current execution context and turn it into an instance of
* ::rb_cBinding.
*
* @return An instance of ::rb_cBinding.
*/
VALUE rb_binding_new(void);
/**
* Creates a method object. A method object is a proc-like object that you can
* "call". Note that a method object snapshots the method at the time the
* object is created:
*
* ```ruby
* class Foo
* def foo
* return 1
* end
* end
*
* obj = Foo.new.method(:foo)
*
* class Foo
* def foo
* return 2
* end
* end
*
* obj.call # => 1, not 2.
* ```
*
* @param[in] recv Receiver of the method.
* @param[in] mid Method name, in either String or Symbol.
* @exception rb_eNoMethodError No such method.
* @return An instance of ::rb_cMethod.
*/
VALUE rb_obj_method(VALUE recv, VALUE mid);
/**
* Queries if the given object is a method.
*
* @note This is about the object's data structure, not its class etc.
* @param[in] recv Object in question.
* @retval RUBY_Qtrue It is a method.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_obj_is_method(VALUE recv);
/**
* Evaluates the passed method with the passed arguments.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] recv The method object to call.
* @exception rb_eTypeError `recv` is not a method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method returns.
*/
VALUE rb_method_call(int argc, const VALUE *argv, VALUE recv);
/**
* Identical to rb_method_call(), except you can specify how to handle the last
* element of the given array.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] recv The method object to call.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `args`' last is not a keyword argument.
* - RB_PASS_KEYWORDS `args`' last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eTypeError `recv` is not a method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method returns.
*/
VALUE rb_method_call_kw(int argc, const VALUE *argv, VALUE recv, int kw_splat);
/**
* Identical to rb_proc_call(), except you can additionally pass a proc as a
* block.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] recv The method object to call.
* @param[in] proc Proc as a passed block.
* @exception rb_eTypeError `recv` is not a method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method returns.
*/
VALUE rb_method_call_with_block(int argc, const VALUE *argv, VALUE recv, VALUE proc);
/**
* Identical to rb_method_call_with_block(), except you can specify how to
* handle the last element of the given array. It can also be seen as a
* routine identical to rb_method_call_kw(), except you can additionally pass
* another proc object as a block.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] recv The method object to call.
* @param[in] proc Proc as a passed block.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `args`' last is not a keyword argument.
* - RB_PASS_KEYWORDS `args`' last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eTypeError `recv` is not a method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method returns.
*/
VALUE rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE recv, VALUE proc, int kw_splat);
/**
* Queries the number of mandatory arguments of the method defined in the given
* module. If it is declared to take no arguments, returns `0`. If it takes
* exactly `n` arguments, returns `n`. If it has optional arguments, returns
* `-n-1`, where `n` is the number of mandatory arguments. Keyword arguments
* will be considered as a single additional argument, that argument being
* mandatory if any keyword argument is mandatory.
*
* @param[in] mod Namespace to search a method for.
* @param[in] mid Method id.
* @retval 0 It takes no arguments.
* @retval >0 It takes exactly this number of arguments.
* @retval <0 It takes optional arguments.
*/
int rb_mod_method_arity(VALUE mod, ID mid);
/**
* Identical to rb_mod_method_arity(), except it searches for singleton methods
* rather than instance methods.
*
* @param[in] obj Object to search for a singleton method.
* @param[in] mid Method id.
* @retval 0 It takes no arguments.
* @retval >0 It takes exactly this number of arguments.
* @retval <0 It takes optional arguments.
*/
int rb_obj_method_arity(VALUE obj, ID mid);
/* eval.c */
RBIMPL_ATTR_NONNULL((1))
/**
* Protects a function call from potential global escapes from the function.
* Such global escapes include exceptions, `throw`, `break`, for example.
*
* It first calls the function func with `args` as the argument. If no global
* escape occurred during the function, it returns the result and `*state` is
* zero. Otherwise, it returns ::RUBY_Qnil and sets `*state` to nonzero. If
* `state` is `NULL`, it is not set in both cases.
*
* @param[in] func A function that potentially escapes globally.
* @param[in] args Passed as-is to `func`.
* @param[out] state State of execution.
* @return What `func` returns, or an undefined value when it did not
* return.
* @post `*state` is set to zero if succeeded. Nonzero otherwise.
* @warning You have to clear the error info with `rb_set_errinfo(Qnil)` if
* you decide to ignore the caught exception.
* @see rb_eval_string_protect()
* @see rb_load_protect()
*
* @internal
*
* The "undefined value" described above is in fact ::RUBY_Qnil for now. But
* @shyouhei doesn't think that we would never change that.
*
* Though not a part of our public API, `state` is in fact an
* enum ruby_tag_type. You can see the potential "nonzero" values by looking
* at vm_core.h.
*/
VALUE rb_protect(VALUE (*func)(VALUE args), VALUE args, int *state);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_PROC_H */
include/ruby/internal/intern/re.h 0000644 00000021351 15040330602 0013035 0 ustar 00 #ifndef RBIMPL_INTERN_RE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cRegexp.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* re.c */
/**
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* This was a function that switched between memcmp and rb_memcicmp depending
* on then-called `ruby_ignorecase`, or the `$=` global variable. That feature
* was abandoned in sometime around version 1.9.0.
*/
#define rb_memcmp memcmp
/**
* Identical to st_locale_insensitive_strcasecmp(), except it is timing safe
* and returns something different.
*
* @param[in] s1 Comparison LHS.
* @param[in] s2 Comparison RHS.
* @param[in] n Comparison shall stop after first `n` bytes are scanned.
* @retval <0 `s1` is "less" than `s2`.
* @retval 0 Both sides converted into lowercase would be identical.
* @retval >0 `s1` is "greater" than `s2`.
* @note The "case" here means that of the POSIX Locale.
*
* @internal
*
* Can accept NULLs as long as n is also 0, and returns 0.
*/
int rb_memcicmp(const void *s1,const void *s2, long n);
/**
* Asserts that the given MatchData is "occupied". MatchData shares its
* backend storages with its Regexp object. But programs can destructively
* tamper its contents. Calling this function beforehand shall prevent such
* modifications to spill over into other objects.
*
* @param[out] md Target instance of ::rb_cMatch.
* @post The object is "busy".
*
* @internal
*
* There is rb_match_unbusy internally, but extension libraries are left unable
* to do so.
*/
void rb_match_busy(VALUE md);
/**
* Identical to rb_reg_nth_match(), except it just returns Boolean. This could
* skip allocating a returning string, resulting in reduced memory footprints
* if applicable.
*
* @param[in] n Match index.
* @param[in] md An instance of ::rb_cMatch.
* @exception rb_eTypeError `md` is not initialised.
* @retval RUBY_Qnil There is no `n`-th capture.
* @retval RUBY_Qfalse There is a `n`-th capture and is empty.
* @retval RUBY_Qtrue There is a `n`-th capture that has something.
*
* @internal
*
* @shyouhei wonders: why there are both rb_reg_match_defined() and
* rb_match_nth_defined, which are largely the same things, but do not share
* their implementations at all?
*/
VALUE rb_reg_nth_defined(int n, VALUE md);
/**
* Queries the nth captured substring.
*
* @param[in] n Match index.
* @param[in] md An instance of ::rb_cMatch.
* @exception rb_eTypeError `md` is not initialised.
* @retval RUBY_Qnil There is no `n`-th capture.
* @retval otherwise An allocated instance of ::rb_cString containing
* the contents captured.
*/
VALUE rb_reg_nth_match(int n, VALUE md);
/**
* Queries the index of the given named capture. Captures could be named. But
* that doesn't mean named ones are not indexed. A regular expression can mix
* named and non-named captures, and they are all indexed. This function
* converts from a name to its index.
*
* @param[in] match An instance of ::rb_cMatch.
* @param[in] backref Capture name, in String, Symbol, or Numeric.
* @exception rb_eIndexError No such named capture.
* @return The index of the given name.
*/
int rb_reg_backref_number(VALUE match, VALUE backref);
/**
* This just returns the argument, stringified. What a poor name.
*
* @param[in] md An instance of ::rb_cMatch.
* @return Its 0th capture (i.e. entire matched string).
*/
VALUE rb_reg_last_match(VALUE md);
/**
* The portion of the original string before the given match.
*
* @param[in] md An instance of ::rb_cMatch.
* @return Its "prematch". This is perl's ``$```.
*/
VALUE rb_reg_match_pre(VALUE md);
/**
* The portion of the original string after the given match.
*
* @param[in] md An instance of ::rb_cMatch.
* @return Its "postmatch". This is perl's `$'`.
*/
VALUE rb_reg_match_post(VALUE md);
/**
* The portion of the original string that captured at the very last.
*
* @param[in] md An instance of ::rb_cMatch.
* @return Its "lastmatch". This is perl's `$+`.
*/
VALUE rb_reg_match_last(VALUE md);
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_REG_NEW_STR 1
/**
* Identical to rb_reg_new(), except it takes the expression in Ruby's string
* instead of C's.
*
* @param[in] src Source code in String.
* @param[in] opts Options e.g. ONIG_OPTION_MULTILINE.
* @exception rb_eRegexpError `src` and `opts` do not interface.
* @return Allocated new instance of ::rb_cRegexp.
*/
VALUE rb_reg_new_str(VALUE src, int opts);
RBIMPL_ATTR_NONNULL(())
/**
* Creates a new Regular expression.
*
* @param[in] src Source code.
* @param[in] len `strlen(src)`.
* @param[in] opts Options e.g. ONIG_OPTION_MULTILINE.
* @return Allocated new instance of ::rb_cRegexp.
*/
VALUE rb_reg_new(const char *src, long len, int opts);
/**
* Allocates an instance of ::rb_cRegexp.
*
* @private
*
* Nobody should call this function. Regular expressions that are not
* initialised must not exist in the wild.
*/
VALUE rb_reg_alloc(void);
/**
* Initialises an instance of ::rb_cRegexp.
*
* @private
*
* This just raises for ordinal regexp objects. Extension libraries must not
* use.
*/
VALUE rb_reg_init_str(VALUE re, VALUE s, int options);
/**
* This is the match operator.
*
* @param[in] re An instance of ::rb_cRegexp.
* @param[in] str An instance of ::rb_cString.
* @exception rb_eTypeError `str` is not a string.
* @exception rb_eRegexpError Error inside of Onigmo (unlikely).
* @retval RUBY_Qnil Match failed.
* @retval otherwise Matched position (character index inside of
* `str`).
* @post `Regexp.last_match` is updated.
* @post `$&`, `$~`, etc., are updated.
* @note If you do this in ruby, named captures are assigned to local
* variable of the local scope. But that doesn't happen here. The
* assignment is done by the interpreter.
*/
VALUE rb_reg_match(VALUE re, VALUE str);
/**
* Identical to rb_reg_match(), except it matches against rb_lastline_get()
* (or, the `$_`).
*
* @param[in] re An instance of ::rb_cRegexp.
* @exception rb_eRegexpError Error inside of Onigmo (unlikely).
* @retval RUBY_Qnil Match failed or `$_` is absent.
* @retval otherwise Matched position (character index inside of
* `$_`).
* @post `Regexp.last_match` is updated.
* @post `$&`, `$~`, etc., are updated.
*/
VALUE rb_reg_match2(VALUE re);
/**
* Queries the options of the passed regular expression.
*
* @param[in] re An instance of ::rb_cRegexp.
* @return Its options.
* @note Possible return values are defined in Onigmo.h.
*/
int rb_reg_options(VALUE re);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RE_H */
include/ruby/internal/intern/thread.h 0000644 00000044034 15040330602 0013701 0 ustar 00 #ifndef RBIMPL_INTERN_THREAD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_THREAD_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cThread.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/config.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
struct timeval;
/* thread.c */
/**
* Tries to switch to another thread. This function blocks until the current
* thread re-acquires the GVL.
*
* @exception rb_eInterrupt Operation interrupted.
*/
void rb_thread_schedule(void);
/**
* Blocks the current thread until the given file descriptor is ready to be
* read.
*
* @param[in] fd A file descriptor.
* @exception rb_eIOError Closed stream.
* @exception rb_eSystemCallError Situations like EBADF.
*/
int rb_thread_wait_fd(int fd);
/**
* Identical to rb_thread_wait_fd(), except it blocks the current thread until
* the given file descriptor is ready to be written.
*
* @param[in] fd A file descriptor.
* @exception rb_eIOError Closed stream.
* @exception rb_eSystemCallError Situations like EBADF.
*/
int rb_thread_fd_writable(int fd);
/**
* Notifies a closing of a file descriptor to other threads. Multiple threads
* can wait for the given file descriptor at once. If such file descriptor is
* closed, threads need to start propagating their exceptions. This is the API
* to kick that process.
*
* @param[in] fd A file descriptor.
* @note This function blocks until all the threads waiting for such fd
* have woken up.
*/
void rb_thread_fd_close(int fd);
/**
* Checks if the thread this function is running is the only thread that is
* currently alive.
*
* @retval 1 Yes it is.
* @retval 0 No it isn't.
*
* @internal
*
* Above description is in fact inaccurate. There are Ractors these days.
*/
int rb_thread_alone(void);
/**
* Blocks for the given period of time.
*
* @warning This function can be interrupted by signals.
* @param[in] sec Duration in seconds.
* @exception rb_eInterrupt Interrupted.
*/
void rb_thread_sleep(int sec);
/**
* Blocks indefinitely.
*
* @exception rb_eInterrupt Interrupted.
*/
void rb_thread_sleep_forever(void);
/**
* Identical to rb_thread_sleep_forever(), except the thread calling this
* function is considered "dead" when our deadlock checker is triggered.
*
* @exception rb_eInterrupt Interrupted.
*/
void rb_thread_sleep_deadly(void);
/**
* Stops the current thread. This is not the end of the thread's lifecycle. A
* stopped thread can later be woken up.
*
* @exception rb_eThreadError Stopping this thread would deadlock.
* @retval ::RUBY_Qnil Always.
*
* @internal
*
* The return value makes no sense at all.
*/
VALUE rb_thread_stop(void);
/**
* Marks a given thread as eligible for scheduling.
*
* @note It may still remain blocked on I/O.
* @note This does not invoke the scheduler itself.
*
* @param[out] thread Thread in question to wake up.
* @exception rb_eThreadError Stop flogging a dead horse.
* @return The passed thread.
* @post The passed thread is made runnable.
*/
VALUE rb_thread_wakeup(VALUE thread);
/**
* Identical to rb_thread_wakeup(), except it doesn't raise on an already
* killed thread.
*
* @param[out] thread A thread to wake up.
* @retval RUBY_Qnil `thread` is already killed.
* @retval otherwise `thread` is alive.
* @post The passed thread is made runnable, unless killed.
*/
VALUE rb_thread_wakeup_alive(VALUE thread);
/**
* This is a rb_thread_wakeup() + rb_thread_schedule() combo.
*
* @note There is no guarantee that this function yields to the passed
* thread. It may still remain blocked on I/O.
* @param[out] thread Thread in question to wake up.
* @exception rb_eThreadError Stop flogging a dead horse.
* @return The passed thread.
*/
VALUE rb_thread_run(VALUE thread);
/**
* Terminates the given thread. Unlike a stopped thread, a killed thread could
* never be revived. This function does return, when passed e.g. an already
* killed thread. But if the passed thread is the only one, or a special
* thread called "main", then it also terminates the entire process.
*
* @param[out] thread The thread to terminate.
* @exception rb_eFatal The passed thread is the running thread.
* @exception rb_eSystemExit The passed thread is the last thread.
* @return The passed thread.
* @post Either the passed thread, or the process entirely, is killed.
*
* @internal
*
* It seems killing the main thread also kills the entire process even if there
* are multiple running ractors. No idea why.
*/
VALUE rb_thread_kill(VALUE thread);
RBIMPL_ATTR_NONNULL((1))
/**
* Creates a Ruby thread that is backended by a C function.
*
* @param[in] f The function to run on a thread.
* @param[in,out] g Passed through to `f`.
* @exception rb_eThreadError Could not create a ruby thread.
* @exception rb_eSystemCallError Situations like `EPERM`.
* @return Allocated instance of ::rb_cThread.
* @note This doesn't wait for anything.
*/
VALUE rb_thread_create(VALUE (*f)(void *g), void *g);
/**
* Identical to rb_thread_sleep(), except it takes struct `timeval` instead.
*
* @warning This function can be interrupted by signals.
* @param[in] time Duration.
* @exception rb_eInterrupt Interrupted.
*/
void rb_thread_wait_for(struct timeval time);
/**
* Obtains the "current" thread.
*
* @return The current thread of the current ractor of the current execution
* context.
* @pre This function must be called from a thread controlled by ruby.
*/
VALUE rb_thread_current(void);
/**
* Obtains the "main" thread. There are threads called main. Historically the
* (only) main thread was the one which runs when the process boots. Now that
* we have Ractor, there are more than one main threads.
*
* @return The main thread of the current ractor of the current execution
* context.
* @pre This function must be called from a thread controlled by ruby.
*/
VALUE rb_thread_main(void);
/**
* This badly named function reads from a Fiber local storage. When this
* function was born there was no such thing like a Fiber. The world was
* innocent. But now... This is a Fiber local storage. Sorry.
*
* @param[in] thread Thread that the target Fiber is running.
* @param[in] key The name of the Fiber local storage to read.
* @retval RUBY_Qnil No such storage.
* @retval otherwise The value stored at `key`.
* @note There in fact are "true" thread local storage, but Ruby doesn't
* provide any interface of them to you, C programmers.
*/
VALUE rb_thread_local_aref(VALUE thread, ID key);
/**
* This badly named function writes to a Fiber local storage. When this
* function was born there was no such thing like a Fiber. The world was
* innocent. But now... This is a Fiber local storage. Sorry.
*
* @param[in] thread Thread that the target Fiber is running.
* @param[in] key The name of the Fiber local storage to write.
* @param[in] val The new value of the storage.
* @exception rb_eFrozenError `thread` is frozen.
* @return The passed `val` as-is.
* @post Fiber local storage `key` has value of `val`.
* @note There in fact are "true" thread local storage, but Ruby doesn't
* provide any interface of them to you, C programmers.
*/
VALUE rb_thread_local_aset(VALUE thread, ID key, VALUE val);
/**
* A `pthread_atfork(3posix)`-like API. Ruby expects its child processes to
* call this function at the very beginning of their processes. If you plan to
* fork a process don't forget to call it.
*/
void rb_thread_atfork(void);
/**
* :FIXME: situation of this function is unclear. It seems nobody uses it.
* Maybe a good idea to KonMari.
*/
void rb_thread_atfork_before_exec(void);
/**
* "Recursion" API entry point. This basically calls the given function with
* the given arguments, but additionally with recursion flag. The flag is set
* to 1 if the execution have already experienced the passed `g` parameter
* before.
*
* @param[in] f The function that possibly recurs.
* @param[in,out] g Passed as-is to `f`.
* @param[in,out] h Passed as-is to `f`.
* @return The return value of f.
*/
VALUE rb_exec_recursive(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);
/**
* Identical to rb_exec_recursive(), except it checks for the recursion on the
* ordered pair of `{ g, p }` instead of just `g`.
*
* @param[in] f The function that possibly recurs.
* @param[in,out] g Passed as-is to `f`.
* @param[in] p Paired object for recursion detection.
* @param[in,out] h Passed as-is to `f`.
*/
VALUE rb_exec_recursive_paired(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);
/**
* Identical to rb_exec_recursive(), except it calls `f` for outermost
* recursion only. Inner recursions yield calls to rb_throw_obj().
*
* @param[in] f The function that possibly recurs.
* @param[in,out] g Passed as-is to `f`.
* @param[in,out] h Passed as-is to `f`.
* @return The return value of f.
*
* @internal
*
* It seems nobody uses the "it calls rb_throw_obj()" part of this function.
* @shyouhei doesn't understand the needs.
*/
VALUE rb_exec_recursive_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);
/**
* Identical to rb_exec_recursive_outer(), except it checks for the recursion
* on the ordered pair of `{ g, p }` instead of just `g`. It can also be seen
* as a routine identical to rb_exec_recursive_paired(), except it calls `f`
* for outermost recursion only. Inner recursions yield calls to
* rb_throw_obj().
*
* @param[in] f The function that possibly recurs.
* @param[in,out] g Passed as-is to `f`.
* @param[in] p Paired object for recursion detection.
* @param[in,out] h Passed as-is to `f`.
*
* @internal
*
* It seems nobody uses the "it calls rb_throw_obj()" part of this function.
* @shyouhei doesn't understand the needs.
*/
VALUE rb_exec_recursive_paired_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);
/**
* This is the type of UBFs. An UBF is a function that unblocks a blocking
* region. For instance when a thread is blocking due to `pselect(3posix)`, it
* is highly expected that `pthread_kill(3posix)` can interrupt the system call
* and the thread could revive. Or when a thread is blocking due to
* `waitpid(3posix)`, it is highly expected that killing the waited process
* should suffice. An UBF is a function that does such things. Designing your
* own UBF needs deep understanding of why your blocking region blocks, how
* threads work in ruby, and a matter of luck. It often is the case you simply
* cannot cancel something that had already begun.
*
* @see rb_thread_call_without_gvl()
*/
typedef void rb_unblock_function_t(void *);
/**
* @private
*
* This is an implementation detail. Must be a mistake to be here.
*
* @internal
*
* Why is this function type different from what rb_thread_call_without_gvl()
* takes?
*/
typedef VALUE rb_blocking_function_t(void *);
/**
* Checks for interrupts. In ruby, signals are masked by default. You can
* call this function at will to check if there are pending signals. In case
* there are, they would be handled in this function.
*
* If your extension library has a function that takes a long time, consider
* calling it periodically.
*
* @note It might switch to another thread.
*/
void rb_thread_check_ints(void);
/**
* Checks if the thread's execution was recently interrupted. If called from
* that thread, this function can be used to detect spurious wake-ups.
*
* @param[in] thval Thread in question.
* @retval 0 The thread was not interrupted.
* @retval otherwise The thread was interrupted recently.
*
* @internal
*
* Above description is not a lie. But actually the return value is an opaque
* trap vector. If you know which bit means which, you can know what happened.
*/
int rb_thread_interrupted(VALUE thval);
/**
* A special UBF for blocking IO operations. You need deep understanding of
* what this actually do before using. Basically you should not use it from
* extension libraries. It is too easy to mess up.
*/
#define RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1)
/**
* A special UBF for blocking process operations. You need deep understanding
* of what this actually do before using. Basically you should not use it from
* extension libraries. It is too easy to mess up.
*/
#define RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1)
/* thread_sync.c */
/**
* Creates a mutex.
*
* @return An allocated instance of rb_cMutex.
*/
VALUE rb_mutex_new(void);
/**
* Queries if there are any threads that holds the lock.
*
* @param[in] mutex The mutex in question.
* @retval RUBY_Qtrue The mutex is locked by someone.
* @retval RUBY_Qfalse The mutex is not locked by anyone.
*/
VALUE rb_mutex_locked_p(VALUE mutex);
/**
* Attempts to lock the mutex, without waiting for other threads to unlock it.
* Failure in locking the mutex can be detected by the return value.
*
* @param[out] mutex The mutex to lock.
* @retval RUBY_Qtrue Successfully locked by the current thread.
* @retval RUBY_Qfalse Otherwise.
* @note This function also returns ::RUBY_Qfalse when the mutex is
* already owned by the calling thread itself.
*/
VALUE rb_mutex_trylock(VALUE mutex);
/**
* Attempts to lock the mutex. It waits until the mutex gets available.
*
* @param[out] mutex The mutex to lock.
* @exception rb_eThreadError Recursive deadlock situation.
* @return The passed mutex.
* @post The mutex is owned by the current thread.
*/
VALUE rb_mutex_lock(VALUE mutex);
/**
* Releases the mutex.
*
* @param[out] mutex The mutex to unlock.
* @exception rb_eThreadError The mutex is not owned by the current thread.
* @return The passed mutex.
* @post Upon successful return the passed mutex is no longer owned by
* the current thread.
*/
VALUE rb_mutex_unlock(VALUE mutex);
/**
* Releases the lock held in the mutex and waits for the period of time;
* reacquires the lock on wakeup.
*
* @pre The lock has to be owned by the current thread beforehand.
* @param[out] self The target mutex.
* @param[in] timeout Duration, in seconds, in ::rb_cNumeric.
* @exception rb_eArgError `timeout` is negative.
* @exception rb_eRangeError `timeout` is out of range of `time_t`.
* @exception rb_eThreadError The mutex is not owned by the current thread.
* @return Number of seconds it actually slept.
* @warning It is a failure not to check the return value. This function
* can return spuriously for various reasons. Maybe other threads
* can rb_thread_wakeup(). Maybe an end user can press the
* Control and C key from the interactive console. On the other
* hand it can also take longer than the specified. The mutex
* could be locked by someone else. It waits then.
* @post Upon successful return the passed mutex is owned by the current
* thread.
*
* @internal
*
* This function is called from `ConditionVariable#wait`. So it is not a
* deprecated feature. However @shyouhei have never seen any similar mutex
* primitive available in any other languages than Ruby.
*
* EDIT: In 2021, @shyouhei asked @ko1 in person about this API. He answered
* that it is his invention. The motivation behind its design is to eliminate
* needs of condition variables as primitives. Unlike other languages, Ruby's
* `ConditionVariable` class was written in pure-Ruby initially. We don't have
* to implement machine-native condition variables in assembly each time we
* port Ruby to a new architecture. This function made it possible. "I felt I
* was a genius when this idea came to me", said @ko1.
*
* `rb_cConditionVariable` is now written in C for speed, though.
*/
VALUE rb_mutex_sleep(VALUE self, VALUE timeout);
/**
* Obtains the lock, runs the passed function, and releases the lock when it
* completes.
*
* @param[out] mutex The mutex to lock.
* @param[in] func What to do during the mutex is locked.
* @param[in,out] arg Passed as-is to `func`.
*/
VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_THREAD_H */
include/ruby/internal/intern/cont.h 0000644 00000026665 15040330602 0013407 0 ustar 00 #ifndef RBIMPL_INTERN_CONT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_CONT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to rb_cFiber.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/iterator.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* cont.c */
/**
* Creates a Fiber instance from a C-backended block.
*
* @param[in] func A function, to become the fiber's body.
* @param[in] callback_obj Passed as-is to `func`.
* @return An allocated new instance of rb_cFiber, which is ready to be
* "resume"d.
*/
VALUE rb_fiber_new(rb_block_call_func_t func, VALUE callback_obj);
/**
* Creates a Fiber instance from a C-backended block with the specified
* storage.
*
* If the given storage is Qundef or Qtrue, this function is equivalent to
* rb_fiber_new() which inherits storage from the current fiber.
*
* Specifying Qtrue is experimental and may be changed in the future.
*
* If the given storage is Qnil, this function will lazy initialize the
* internal storage which starts of empty (without any inheritance).
*
* Otherwise, the given storage is used as the internal storage.
*
* @param[in] func A function, to become the fiber's body.
* @param[in] callback_obj Passed as-is to `func`.
* @param[in] storage The way to set up the storage for the fiber.
* @return An allocated new instance of rb_cFiber, which is ready to be
* "resume"d.
*/
VALUE rb_fiber_new_storage(rb_block_call_func_t func, VALUE callback_obj, VALUE storage);
/**
* Queries the fiber which is calling this function. Any ruby execution
* context has its fiber, either explicitly or implicitly.
*
* @return The current fiber.
*/
VALUE rb_fiber_current(void);
/**
* Queries the liveness of the passed fiber. "Alive" in this context means
* that the fiber can still be resumed. Once it reaches is its end of
* execution, this function returns ::RUBY_Qfalse.
*
* @param[in] fiber A target fiber.
* @retval RUBY_Qtrue It is.
* @retval RUBY_Qfalse It isn't.
*/
VALUE rb_fiber_alive_p(VALUE fiber);
/**
* Queries if an object is a fiber.
*
* @param[in] obj Arbitrary ruby object.
* @retval RUBY_Qtrue It is.
* @retval RUBY_Qfalse It isn't.
*/
VALUE rb_obj_is_fiber(VALUE obj);
/**
* Resumes the execution of the passed fiber, either from the point at which
* the last rb_fiber_yield() was called if any, or at the beginning of the
* fiber body if it is the first call to this function.
*
* Other arguments are passed into the fiber's body, either as return values of
* rb_fiber_yield() in case it switches to there, or as the block parameter of
* the fiber body if it switches to the beginning of the fiber.
*
* The return value of this function is either the value passed to previous
* rb_fiber_yield() call, or the ultimate evaluated value of the entire fiber
* body if the execution reaches the end of it.
*
* When an exception happens inside of a fiber it propagates to this function.
*
* ```ruby
* f = Fiber.new do |i|
* puts "<x> =>> #{i}"
* puts "<y> <-- #{i + 1}"
* j = Fiber.yield(i + 1)
* puts "<z> =>> #{j}"
* puts "<w> <-- #{j + 1}"
* next j + 1
* end
*
* puts "[a] <-- 1"
* p = f.resume(1)
* puts "[b] =>> #{p}"
* puts "[c] <-- #{p + 1}"
* q = f.resume(p + 1)
* puts "[d] =>> #{q}"
* ```
*
* Above program executes in `[a] <x> <y> [b] [c] <z> <w> [d]`.
*
* @param[out] fiber The fiber to resume.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed (somehow) to `fiber`.
* @exception rb_eFiberError `fib` is terminated etc.
* @exception rb_eException Any exceptions happen in `fiber`.
* @return (See above)
* @note This function _does_ return.
*
* @internal
*
* @shyouhei expected this function to raise ::rb_eFrozenError for frozen
* fibers but it doesn't in practice. Intentional or ...?
*/
VALUE rb_fiber_resume(VALUE fiber, int argc, const VALUE *argv);
/**
* Identical to rb_fiber_resume(), except you can specify how to handle the
* last element of the given array.
*
* @param[out] fiber The fiber to resume.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed (somehow) to `fiber`.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eFiberError `fiber` is terminated etc.
* @exception rb_eException Any exceptions happen in `fiber`.
* @return Either what was yielded or the last value of the fiber body.
*/
VALUE rb_fiber_resume_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);
/**
* Yields the control back to the point where the current fiber was resumed.
* The passed objects would be the return value of rb_fiber_resume(). This
* fiber then suspends its execution until next time it is resumed.
*
* This function can also raise arbitrary exceptions injected from outside of
* the fiber using rb_fiber_raise().
*
* ```ruby
* exc = Class.new Exception
*
* f = Fiber.new do
* Fiber.yield
* rescue exc => e
* puts e.message
* end
*
* f.resume
* f.raise exc, "Hi!"
* ```
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed to rb_fiber_resume().
* @exception rb_eException (See above)
* @return (See rb_fiber_resume() for details)
*/
VALUE rb_fiber_yield(int argc, const VALUE *argv);
/**
* Identical to rb_fiber_yield(), except you can specify how to handle the last
* element of the given array.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed to rb_fiber_resume().
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eException What was raised using `Fiber#raise`.
* @return (See rb_fiber_resume() for details)
*/
VALUE rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat);
/**
* Transfers control to another fiber, resuming it from where it last stopped
* or starting it if it was not resumed before. The calling fiber will be
* suspended much like in a call to rb_fiber_yield().
*
* The fiber which receives the transfer call treats it much like a resume
* call. Arguments passed to transfer are treated like those passed to resume.
*
* The two style of control passing to and from fiber (one is rb_fiber_resume()
* and rb_fiber_yield(), another is rb_fiber_transfer() to and from fiber)
* can't be freely mixed.
*
* - If the Fiber's lifecycle had started with transfer, it will never be
* able to yield or be resumed control passing, only finish or transfer
* back. (It still can resume other fibers that are allowed to be
* resumed.)
*
* - If the Fiber's lifecycle had started with resume, it can yield or
* transfer to another Fiber, but can receive control back only the way
* compatible with the way it was given away: if it had transferred, it
* only can be transferred back, and if it had yielded, it only can be
* resumed back. After that, it again can transfer or yield.
*
* If those rules are broken, rb_eFiberError is raised.
*
* For an individual Fiber design, yield/resume is easier to use (the Fiber
* just gives away control, it doesn't need to think about who the control is
* given to), while transfer is more flexible for complex cases, allowing to
* build arbitrary graphs of Fibers dependent on each other.
*
* @param[out] fiber Explicit control destination.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed to rb_fiber_resume().
* @exception rb_eFiberError (See above)
* @exception rb_eException What was raised using `Fiber#raise`.
* @return (See rb_fiber_resume() for details)
*/
VALUE rb_fiber_transfer(VALUE fiber, int argc, const VALUE *argv);
/**
* Identical to rb_fiber_transfer(), except you can specify how to handle the
* last element of the given array.
*
* @param[out] fiber Explicit control destination.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed to rb_fiber_resume().
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eFiberError (See above)
* @exception rb_eException What was raised using `Fiber#raise`.
* @return (See rb_fiber_resume() for details)
*/
VALUE rb_fiber_transfer_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);
/**
* Identical to rb_fiber_resume() but instead of resuming normal execution of
* the passed fiber, it raises the given exception in it. From inside of the
* fiber this would be seen as if rb_fiber_yield() raised.
*
* This function does return in case the passed fiber gracefully handled the
* passed exception. But if it does not, the raised exception propagates out
* of the passed fiber; this function then does not return.
*
* Parameters are passed to rb_make_exception() to create an exception object.
* See its document for what are allowed here.
*
* It is a failure to call this function against a fiber which is resuming,
* have never run yet, or has already finished running.
*
* @param[out] fiber Where exception is raised.
* @param[in] argc Passed as-is to rb_make_exception().
* @param[in] argv Passed as-is to rb_make_exception().
* @exception rb_eFiberError `fiber` is terminated etc.
* @return (See rb_fiber_resume() for details)
*/
VALUE rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_CONT_H */
include/ruby/internal/intern/vm.h 0000644 00000040750 15040330602 0013055 0 ustar 00 #ifndef RBIMPL_INTERN_VM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_VM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to rb_cRubyVM.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* vm.c */
/**
* Resembles `__LINE__`.
*
* @retval 0 Current execution context not in a ruby method.
* @retval otherwise The current line number of the current thread of the
* current ractor of the current execution context.
*/
int rb_sourceline(void);
/**
* Resembles `__FILE__`.
*
* @retval 0 Current execution context not in a ruby method.
* @retval otherwise The current source path of the current thread of the
* current ractor of the current execution context.
* @note This may or may not be an absolute path.
*/
const char *rb_sourcefile(void);
/**
* Resembles `__method__`.
*
* @param[out] idp Return buffer for method id.
* @param[out] klassp Return buffer for class.
* @retval 0 Current execution context not in a method.
* @retval 1 Successful return.
* @post Upon successful return `*idp` and `*klassp` are updated to have
* the current method name and its defined class respectively.
* @note Both parameters can be `NULL`.
*/
int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
/* vm_eval.c */
/**
* Identical to rb_funcallv(), except it returns ::RUBY_Qundef instead of
* raising ::rb_eNoMethodError.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @retval RUBY_Qundef `recv` doesn't respond to `mid`.
* @retval otherwise What the method evaluates to.
*/
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv);
/**
* Identical to rb_check_funcall(), except you can specify how to handle the
* last element of the given array. It can also be seen as a routine identical
* to rb_funcallv_kw(), except it returns ::RUBY_Qundef instead of raising
* ::rb_eNoMethodError.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @retval RUBY_Qundef `recv` doesn't respond to `mid`.
* @retval otherwise What the method evaluates to.
*/
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
/**
* This API is practically a variant of rb_proc_call_kw() now. Historically
* when there still was a concept called `$SAFE`, this was an API for that.
* But we no longer have that. This function basically ended its role. It
* just remains here because of no harm.
*
* @param[in] cmd A string, or something callable.
* @param[in] arg Argument passed to the call.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `arg`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `arg`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @return What the command evaluates to.
*/
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat);
/**
* Identical to rb_funcallv(), except it takes Ruby's array instead of C's.
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] args An instance of ::RArray.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
* @pre `args` must be an ::RArray. Call `to_ary` beforehand when
* necessary.
*/
VALUE rb_apply(VALUE recv, ID mid, VALUE args);
/**
* Evaluates a string containing Ruby source code, or the given block, within
* the context of the receiver. In order to set the context, the variable
* `self` is set to `recv` while the code is executing, giving the code access
* to `recv`'s instance variables and private methods.
*
* When given a block, `recv` is also passed in as the block's only argument.
*
* When given a string, the optional second and third parameters supply a
* filename and starting line number that are used when reporting compilation
* errors.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv C array of 0 up to 3 elements.
* @param[in] recv The object in question.
* @return What was evaluated.
*/
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE recv);
/**
* Executes the given block within the context of the receiver. In order to
* set the context, the variable `self` is set to `recv` while the code is
* executing, giving the code access to `recv`'s instance variables. Arguments
* are passed as block parameters.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv Arbitrary parameters to be passed to the block.
* @param[in] recv The object in question.
* @return What was evaluated.
* @note Don't confuse this with rb_obj_instance_eval(). The key
* difference is whether you can pass arbitrary parameters to the
* block, like this:
*
* ```ruby
* class Foo
* def initialize
* @foo = 5
* end
* end
* Foo.new.instance_exec(7) {|i| @foo + i } # => 12
* ```
*/
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE recv);
/**
* Identical to rb_obj_instance_eval(), except it evaluates within the context
* of module.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv C array of 0 up to 3 elements.
* @param[in] mod The module in question.
* @pre `mod` must be a Module.
* @return What was evaluated.
*/
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_obj_instance_exec(), except it evaluates within the context
* of module.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv Arbitrary parameters to be passed to the block.
* @param[in] mod The module in question.
* @pre `mod` must be a Module.
* @return What was evaluated.
*/
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod);
/* vm_method.c */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_DEFINE_ALLOC_FUNC 1
/**
* This is the type of functions that ruby calls when trying to allocate an
* object. It is sometimes necessary to allocate extra memory regions for an
* object. When you define a class that uses ::RTypedData, it is typically the
* case. On such situations define a function of this type and pass it to
* rb_define_alloc_func().
*
* @param[in] klass The class that this function is registered.
* @return A newly allocated instance of `klass`.
*/
typedef VALUE (*rb_alloc_func_t)(VALUE klass);
/**
* Sets the allocator function of a class.
*
* @param[out] klass The class to modify.
* @param[in] func An allocator function for the class.
* @pre `klass` must be an instance of Class.
*/
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func);
/**
* Deletes the allocator function of a class. It is sometimes desirable to
* restrict creation of an instance of a class. For example it rarely makes
* sense for a DB adaptor class to allow programmers creating DB row objects
* without querying the DB itself. You can kill sporadic creation of such
* objects then, by nullifying the allocator function using this API. Your
* object shall be allocated using #RB_NEWOBJ_OF() directly.
*
* @param[out] klass The class to modify.
* @pre `klass` must be an instance of Class.
*/
void rb_undef_alloc_func(VALUE klass);
/**
* Queries the allocator function of a class.
*
* @param[in] klass The class in question.
* @pre `klass` must be an instance of Class.
* @retval 0 No allocator function is registered.
* @retval otherwise The allocator function.
*
* @internal
*
* Who cares? @shyouhei finds no practical usage of the return value. Maybe we
* need KonMari.
*/
rb_alloc_func_t rb_get_alloc_func(VALUE klass);
/**
* Clears the inline constant caches associated with a particular ID. Extension
* libraries should not bother with such things. Just forget about this API (or
* even, the presence of constant caches).
*/
void rb_clear_constant_cache_for_id(ID id);
/**
* Resembles `alias`.
*
* @param[out] klass Where to define an alias.
* @param[in] dst New name.
* @param[in] src Existing name.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method named `src`.
* @post `klass` has a method named `dst`, which is the identical to its
* method named `src`.
*/
void rb_alias(VALUE klass, ID dst, ID src);
/**
* This function resembles now-deprecated `Module#attr`.
*
* @param[out] klass Where to define an attribute.
* @param[in] name Name of an instance variable.
* @param[in] need_reader Whether attr_reader is needed.
* @param[in] need_writer Whether attr_writer is needed.
* @param[in] honour_visibility Whether to use the current visibility.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eFrozenError `klass` is frozen.
* @post If `need_reader` is set `klass` has a method named `name`.
* @post If `need_writer` is set `klass` has a method named `name=`.
*
* @internal
*
* The three `int` arguments should have been bool, but there was no such thing
* like a bool when K&R was used in this project.
*/
void rb_attr(VALUE klass, ID name, int need_reader, int need_writer, int honour_visibility);
RBIMPL_ATTR_NONNULL(())
/**
* Removes a method. Don't confuse this to rb_undef_method(), which doesn't
* remove a method. This one resembles `Module#remove_method`.
*
* @param[out] klass The class to remove a method.
* @param[in] name Name of a method to be removed.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method.
* @see rb_undef_method
*/
void rb_remove_method(VALUE klass, const char *name);
/**
* Identical to rb_remove_method(), except it accepts the method name as ::ID.
*
* @param[out] klass The class to remove a method.
* @param[in] mid Name of a method to be removed.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method.
* @see rb_undef
*/
void rb_remove_method_id(VALUE klass, ID mid);
/**
* Queries if the klass has this method. This function has only one line of
* document in the implementation that states "// deprecated". Don't know what
* that means though.
*
* @param[in] klass The class in question.
* @param[in] id The method name to query.
* @param[in] ex Undocumented magic value.
* @retval false Method not found.
* @retval true There is a method.
* @pre `klass` must be a module.
*
* @internal
*
* @shyouhei has no motivation to describe what should be passed to `ex`. It
* seems this function should just be trashed.
*/
int rb_method_boundp(VALUE klass, ID id, int ex);
/**
* Well... Let us hesitate from describing what a "basic definition" is. This
* nuanced concept should have been kept private. Just please. Don't touch
* it. This function is a badly distributed random number generator. Right?
*
* @param[in] klass The class in question.
* @param[in] mid The method name in question.
* @retval 1 It is.
* @retval 0 It isn't.
*/
int rb_method_basic_definition_p(VALUE klass, ID mid);
/**
* Identical to rb_respond_to(), except it additionally takes the visibility
* parameter. This does not make difference unless the object has
* `respond_to?` undefined, but has `respond_to_missing?` defined. That case
* the passed argument becomes the second argument of `respond_to_missing?`.
*
* @param[in] obj The object in question.
* @param[in] mid The method name in question.
* @param[in] private_p This is the second argument of `obj`'s
* `respond_to_missing?`.
* @retval 1 Yes it does.
* @retval 0 No it doesn't.
*/
int rb_obj_respond_to(VALUE obj, ID mid, int private_p);
/**
* Queries if the object responds to the method. This involves calling the
* object's `respond_to?` method.
*
* @param[in] obj The object in question.
* @param[in] mid The method name in question.
* @retval 1 Yes it does.
* @retval 0 No it doesn't.
*/
int rb_respond_to(VALUE obj, ID mid);
RBIMPL_ATTR_NORETURN()
/**
* Raises ::rb_eNotImpError. This function is used as an argument to
* rb_define_method() etc.
*
* ```CXX
* rb_define_method(rb_cFoo, "foo", rb_f_notimplement, -1);
* ```
*
* @param argc Unused parameter.
* @param argv Unused parameter.
* @param obj Unused parameter.
* @param marker Unused parameter.
* @exception rb_eNotImpError Always.
* @return Never returns.
*
* @internal
*
* See also the Q&A section of include/ruby/internal/anyargs.h.
*/
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker);
#if !defined(RUBY_EXPORT) && defined(_WIN32)
RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE, VALUE marker);
#define rb_f_notimplement (*rb_f_notimplement_)
#endif
/* vm_backtrace.c */
/**
* Prints the backtrace out to the standard error. This just confuses people
* for no reason. Evil souls must only use it.
*
* @internal
*
* Actually it is very useful when called from an interactive GDB session.
*/
void rb_backtrace(void);
/**
* Creates the good old fashioned array-of-strings style backtrace info.
*
* @return An array which contains strings, which are the textual
* representations of the backtrace locations of the current thread of
* the current ractor of the current execution context.
* @note Ruby scripts can access more sophisticated
* `Thread::Backtrace::Location`. But it seems there is no way for C
* extensions to use that API.
*/
VALUE rb_make_backtrace(void);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_VM_H */
include/ruby/internal/intern/error.h 0000644 00000023151 15040330602 0013560 0 ustar 00 #ifndef RBIMPL_INTERN_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ERROR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_eException.
*/
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/fl_type.h"
#include "ruby/backward/2/assume.h"
/**
* This macro is used in conjunction with rb_check_arity(). If you pass it to
* the function's last (max) argument, that means the function does not check
* upper limit.
*/
#define UNLIMITED_ARGUMENTS (-1)
#define rb_exc_new2 rb_exc_new_cstr /**< @old{rb_exc_new_cstr} */
#define rb_exc_new3 rb_exc_new_str /**< @old{rb_exc_new_str} */
/** @cond INTERNAL_MACRO */
#define rb_check_arity rb_check_arity
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* error.c */
/**
* Creates an instance of the passed exception class.
*
* @param[in] etype A subclass of ::rb_eException.
* @param[in] ptr Buffer contains error message.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eTypeError `etype` is not a class.
* @exception rb_eArgError `len` is negative.
* @return An instance of `etype`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
*
* @internal
*
* This function works for non-exception classes as well, as long as they take
* one string argument.
*/
VALUE rb_exc_new(VALUE etype, const char *ptr, long len);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_exc_new(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[in] etype A subclass of ::rb_eException.
* @param[in] str A C string (becomes an error message).
* @exception rb_eTypeError `etype` is not a class.
* @return An instance of `etype`.
*/
VALUE rb_exc_new_cstr(VALUE etype, const char *str);
/**
* Identical to rb_exc_new_cstr(), except it takes a Ruby's string instead of
* C's.
*
* @param[in] etype A subclass of ::rb_eException.
* @param[in] str An instance of ::rb_cString.
* @exception rb_eTypeError `etype` is not a class.
* @return An instance of `etype`.
*/
VALUE rb_exc_new_str(VALUE etype, VALUE str);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Raises an instance of ::rb_eLoadError.
*
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eLoadError Always raises this.
* @note It never returns.
*
* @internal
*
* Who needs this? Except ruby itself?
*/
void rb_loaderror(const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_loaderror(), except it additionally takes which file is
* unable to load. The path can be obtained later using `LoadError#path` of
* the raising exception.
*
* @param[in] path What failed.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eLoadError Always raises this.
* @note It never returns.
*/
void rb_loaderror_with_path(VALUE path, const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Raises an instance of ::rb_eNameError. The name can be obtained later using
* `NameError#name` of the raising exception.
*
* @param[in] name What failed.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eNameError Always raises this.
* @note It never returns.
*/
void rb_name_error(ID name, const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_name_error(), except it takes a ::VALUE instead of ::ID.
*
* @param[in] name What failed.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eNameError Always raises this.
* @note It never returns.
*/
void rb_name_error_str(VALUE name, const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Raises an instance of ::rb_eFrozenError. The object can be obtained later
* using `FrozenError#receiver` of the raising exception.
*
* @param[in] recv What is frozen.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eFrozenError Always raises this.
* @note It never returns.
*
* @internal
*
* Note however, that it is often not possible to inspect a frozen object,
* because the inspection itself could be forbidden by the frozen-ness.
*/
void rb_frozen_error_raise(VALUE recv, const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
* Honestly I don't understand the name, but it raises an instance of
* ::rb_eArgError.
*
* @param[in] str A message.
* @param[in] type Another message.
* @exception rb_eArgError Always raises this.
* @note It never returns.
*/
void rb_invalid_str(const char *str, const char *type);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_frozen_error_raise(), except its raising exception has a
* message like "can't modify frozen /what/".
*
* @param[in] what What was frozen.
* @exception rb_eFrozenError Always raises this.
* @note It never returns.
*/
void rb_error_frozen(const char *what);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_error_frozen(), except it takes arbitrary Ruby object
* instead of C's string.
*
* @param[in] what What was frozen.
* @exception rb_eFrozenError Always raises this.
* @note It never returns.
*/
void rb_error_frozen_object(VALUE what);
/**
* Queries if the passed object is frozen.
*
* @param[in] obj Target object to test frozen-ness.
* @exception rb_eFrozenError It is frozen.
* @post Upon successful return it is guaranteed _not_ frozen.
*/
void rb_check_frozen(VALUE obj);
/**
* Ensures that the passed object can be `initialize_copy` relationship. When
* you implement your own one you would better call this at the right beginning
* of your implementation.
*
* @param[in] obj Destination object.
* @param[in] orig Source object.
* @exception rb_eFrozenError `obj` is frozen.
* @post Upon successful return obj is guaranteed safe to copy orig.
*/
void rb_check_copyable(VALUE obj, VALUE orig);
RBIMPL_ATTR_NORETURN()
/**
* @private
*
* This is an implementation detail of rb_scan_args(). You don't have to
* bother.
*
* @pre `argc` is out of range of `min`..`max`, both inclusive.
* @param[in] argc Arbitrary integer.
* @param[in] min Minimum allowed `argc`.
* @param[in] max Maximum allowed `argc`.
* @exception rb_eArgError Always.
*/
MJIT_STATIC void rb_error_arity(int argc, int min, int max);
RBIMPL_SYMBOL_EXPORT_END()
/**
* @deprecated
*
* Does anyone use this? Remain not deleted for compatibility.
*/
#define rb_check_frozen_internal(obj) do { \
VALUE frozen_obj = (obj); \
if (RB_UNLIKELY(RB_OBJ_FROZEN(frozen_obj))) { \
rb_error_frozen_object(frozen_obj); \
} \
} while (0)
/** @alias{rb_check_frozen} */
static inline void
rb_check_frozen_inline(VALUE obj)
{
if (RB_UNLIKELY(RB_OBJ_FROZEN(obj))) {
rb_error_frozen_object(obj);
}
}
/** @alias{rb_check_frozen} */
#define rb_check_frozen rb_check_frozen_inline
/**
* Ensures that the passed integer is in the passed range. When you can use
* rb_scan_args() that is preferred over this one (powerful, descriptive). But
* it can have its own application area.
*
* @param[in] argc Arbitrary integer.
* @param[in] min Minimum allowed `argv`.
* @param[in] max Maximum allowed `argv`, or `UNLIMITED_ARGUMENTS`.
* @exception rb_eArgError `argc` out of range.
* @return The passed `argc`.
* @post Upon successful return `argc` is in range of `min`..`max`, both
* inclusive.
*/
static inline int
rb_check_arity(int argc, int min, int max)
{
if ((argc < min) || (max != UNLIMITED_ARGUMENTS && argc > max))
rb_error_arity(argc, min, max);
return argc;
}
#endif /* RBIMPL_INTERN_ERROR_H */
include/ruby/internal/intern/bignum.h 0000644 00000074054 15040330602 0013720 0 ustar 00 #ifndef RBIMPL_INTERN_BIGNUM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_BIGNUM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to so-called rb_cBignum.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/long_long.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* bignum.c */
/**
* Allocates a bignum object.
*
* @param[in] len Length of the bignum's backend storage, in words.
* @param[in] sign Sign of the bignum.
* @return An allocated new bignum instance.
* @note This only allocates an object, doesn't fill its value in.
*
* @internal
*
* @shyouhei finds it hard to use from extension libraries. `len` is per
* `BDIGIT` but its definition is hidden.
*/
VALUE rb_big_new(size_t len, int sign);
/**
* Queries if the passed bignum instance is a "bigzro". What is a bigzero?
* Well, bignums are for very big integers, but can also represent tiny ones
* like -1, 0, 1. Bigzero are instances of bignums whose values are zero.
* Knowing if a bignum is bigzero can be handy on occasions, like for instance
* detecting division by zero situation.
*
* @param[in] x A bignum.
* @retval 1 It is a bigzero.
* @retval 0 Otherwise.
*/
int rb_bigzero_p(VALUE x);
/**
* Duplicates the given bignum.
*
* @param[in] num A bignum.
* @return An allocated bignum, who is equivalent to `num`.
*/
VALUE rb_big_clone(VALUE num);
/**
* Destructively modify the passed bignum into 2's complement representation.
*
* @note By default bignums are in signed magnitude system.
*
* @param[out] num A bignum to modify.
*/
void rb_big_2comp(VALUE num);
/**
* Normalises the passed bignum. It for instance returns a fixnum of the same
* value if fixnum can represent that number.
*
* @param[out] x Target bignum (can be destructively modified).
* @return An integer of the identical value (can be `x` itself).
*/
VALUE rb_big_norm(VALUE x);
/**
* Destructively resizes the backend storage of the passed bignum.
*
* @param[out] big A bignum.
* @param[in] len New length of `big`'s backend, in words.
*/
void rb_big_resize(VALUE big, size_t len);
RBIMPL_ATTR_NONNULL(())
/**
* Parses C's string to convert into a Ruby's integer. It understands prefixes
* (e.g. `0x`) and underscores.
*
* @param[in] str Stringised representation of the return value.
* @param[in] base Base of conversion. Must be `-36..36` inclusive,
* except `1`. `2..36` means the conversion is done
* according to it, with unmatched prefix understood
* as a part of the result. `-36..-2` means the
* conversion honours prefix when present, or use
* `-base` when absent. `0` is equivalent to `-10`.
* `-1` mandates a prefix. `1` is an error.
* @param[in] badcheck Whether to raise ::rb_eArgError on failure. If
* `0` is passed here this function can return
* `INT2FIX(0)` for parse errors.
* @exception rb_eArgError Failed to parse (and `badcheck` is truthy).
* @return An instance of ::rb_cInteger, which is a numeric interpretation
* of what is written in `str`.
*
* @internal
*
* Not sure if it intentionally accepts `base == -1` or is just buggy. Nobody
* practically uses negative bases these days.
*/
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck);
/**
* Identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's.
*
* @param[in] str Stringised representation of the return
* value.
* @param[in] base Base of conversion. Must be `-36..36`
* inclusive, except `1`. `2..36` means the
* conversion is done according to it, with
* unmatched prefix understood as a part of the
* result. `-36..-2` means the conversion
* honours prefix when present, or use `-base`
* when absent. `0` is equivalent to `-10`.
* `-1` mandates a prefix. `1` is an error.
* @param[in] badcheck Whether to raise ::rb_eArgError on failure.
* If `0` is passed here this function can
* return `INT2FIX(0)` for parse errors.
* @exception rb_eArgError Failed to parse (and `badcheck` is truthy).
* @exception rb_eTypeError `str` is not a string.
* @exception rb_eEncCompatError `str` is not ASCII compatible.
* @return An instance of ::rb_cInteger, which is a numeric interpretation
* of what is written in `str`.
*/
VALUE rb_str_to_inum(VALUE str, int base, int badcheck);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_cstr_to_inum(), except the second argument controls the base
* and badcheck at once. It basically doesn't raise for parse errors, unless
* the base is zero.
*
* This is an older API. New codes might prefer rb_cstr_to_inum().
*
* @param[in] str Stringised representation of the return value.
* @param[in] base Base of conversion. Must be `-36..36` inclusive,
* except `1`. `2..36` means the conversion is done
* according to it, with unmatched prefix understood
* as a part of the result. `-36..-2` means the
* conversion honours prefix when present, or use
* `-base` when absent. `0` is equivalent to `-10`.
* `-1` mandates a prefix. `1` is an error.
* @exception rb_eArgError Failed to parse (and `base` is zero).
* @return An instance of ::rb_cInteger, which is a numeric interpretation
* of what is written in `str`.
*/
VALUE rb_cstr2inum(const char *str, int base);
/**
* Identical to rb_str_to_inum(), except the second argument controls the base
* and badcheck at once. It can also be seen as a routine identical to
* rb_cstr2inum(), except it takes Ruby's strings instead of C's.
*
* This is an older API. New codes might prefer rb_cstr_to_inum().
*
* @param[in] str Stringised representation of the return
* value.
* @param[in] base Base of conversion. Must be `-36..36`
* inclusive, except `1`. `2..36` means the
* conversion is done according to it, with
* unmatched prefix understood as a part of the
* result. `-36..-2` means the conversion
* honours prefix when present, or use `-base`
* when absent. `0` is equivalent to `-10`.
* `-1` mandates a prefix. `1` is an error.
* @exception rb_eArgError Failed to parse (and `base` is zero).
* @exception rb_eTypeError `str` is not a string.
* @exception rb_eEncCompatError `str` is not ASCII compatible.
* @return An instance of ::rb_cInteger, which is a numeric interpretation
* of what is written in `str`.
*/
VALUE rb_str2inum(VALUE str, int base);
/**
* Generates a place-value representation of the passed integer.
*
* @param[in] x An integer to stringify.
* @param[in] base `2` to `36` inclusive for each radix.
* @exception rb_eArgError `base` is out of range.
* @exception rb_eRangeError `x` is too big, cannot represent in string.
* @return An instance of ::rb_cString which represents `x`.
*/
VALUE rb_big2str(VALUE x, int base);
/**
* Converts a bignum into C's `long`.
*
* @param[in] x A bignum.
* @exception rb_eRangeError `x` is out of range of `long`.
* @return The passed value converted into C's `long`.
*/
long rb_big2long(VALUE x);
/** @alias{rb_big2long} */
#define rb_big2int(x) rb_big2long(x)
/**
* Converts a bignum into C's `unsigned long`.
*
* @param[in] x A bignum.
* @exception rb_eRangeError `x` is out of range of `unsigned long`.
* @return The passed value converted into C's `unsigned long`.
*
* @internal
*
* This function can generate a very large positive integer for a negative
* input. For instance applying Ruby's -4,611,686,018,427,387,905 to this
* function yields C's 13,835,058,055,282,163,711 on my machine. This is how
* it has been. Cannot change any longer.
*/
unsigned long rb_big2ulong(VALUE x);
/** @alias{rb_big2long} */
#define rb_big2uint(x) rb_big2ulong(x)
#if HAVE_LONG_LONG
/**
* Converts a bignum into C's `long long`.
*
* @param[in] x A bignum.
* @exception rb_eRangeError `x` is out of range of `long long`.
* @return The passed value converted into C's `long long`.
*/
LONG_LONG rb_big2ll(VALUE);
/**
* Converts a bignum into C's `unsigned long long`.
*
* @param[in] x A bignum.
* @exception rb_eRangeError `x` is out of range of `unsigned long long`.
* @return The passed value converted into C's `unsigned long long`.
*
* @internal
*
* This function can generate a very large positive integer for a negative
* input. For instance applying Ruby's -4,611,686,018,427,387,905 to this
* function yields C's 13,835,058,055,282,163,711 on my machine. This is how
* it has been. Cannot change any longer.
*/
unsigned LONG_LONG rb_big2ull(VALUE);
#endif /* HAVE_LONG_LONG */
RBIMPL_ATTR_NONNULL(())
/**
* Converts a bignum into a series of its parts.
*
* @param[in] val An integer.
* @param[out] buf Return buffer.
* @param[in] num_longs Number of words of `buf`.
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
* @post `buf` is filled with `val`'s 2's complement representation, in
* the host CPU's native byte order, from least significant word
* towards the most significant one, for `num_longs` words.
* @note The "pack" terminology comes from `Array#pack`.
*/
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);
RBIMPL_ATTR_NONNULL(())
/**
* Constructs a (possibly very big) bignum from a series of integers. `buf[0]`
* would be the return value's least significant word; `buf[num_longs-1]` would
* be that of most significant.
*
* @param[in] buf A series of integers.
* @param[in] num_longs Number of words of `buf`.
* @exception rb_eArgError Result would be too big.
* @return An instance of ::rb_cInteger which is an "unpack"-ed value of
* the parameters.
* @note The "unpack" terminology comes from `String#pack`.
*/
VALUE rb_big_unpack(unsigned long *buf, long num_longs);
/* pack.c */
RBIMPL_ATTR_NONNULL(())
/**
* Encodes a Unicode codepoint into its UTF-8 representation.
*
* @param[out] buf Return buffer, must at least be 6 bytes width.
* @param[in] uv An Unicode codepoint.
* @exception rb_eRangeError `uv` is out of Unicode.
* @return Number of bytes written to `buf`
* @post `buf` holds a UTF-8 representation of `uv`.
*/
int rb_uv_to_utf8(char buf[6], unsigned long uv);
/* bignum.c */
/**
* Converts a C's `double` into a bignum.
*
* @param[in] d A value to convert.
* @exception rb_eFloatDomainError `d` is Inf/NaN.
* @return An instance of ::rb_cInteger whose value is approximately `d`.
*
* @internal
*
* @shyouhei is not sure if the result is guaranteed to be the nearest integer
* of `d`.
*/
VALUE rb_dbl2big(double d);
/**
* Converts a bignum into C's `double`.
*
* @param[in] x A bignum.
* @return The passed value converted into C's `double`.
*
* @internal
*
* @shyouhei is not sure if the result is guaranteed to be `x`'s nearest value
* that a `double` can represent.
*/
double rb_big2dbl(VALUE x);
/**
* Compares the passed two bignums.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval -1 `rhs` is bigger than `lhs`.
* @retval 0 They are identical.
* @retval 1 `lhs` is bigger than `rhs`.
* @see rb_num_coerce_cmp()
*/
VALUE rb_big_cmp(VALUE lhs, VALUE rhs);
/**
* Equality, in terms of `==`. This checks if the _value_ is the same, not the
* identity. For instance `1 == 1.0` must hold.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval RUBY_Qtrue They are the same.
* @retval RUBY_Qfalse They are different.
*/
VALUE rb_big_eq(VALUE lhs, VALUE rhs);
/**
* Equality, in terms of `eql?`. Unlike rb_big_eq() it does not convert
* ::rb_cFloat etc. This function returns ::RUBY_Qtrue if and only if both
* parameters are bignums, which represent the identical numerical value.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval RUBY_Qtrue They are identical.
* @retval RUBY_Qfalse They are distinct.
*/
VALUE rb_big_eql(VALUE lhs, VALUE rhs);
/**
* Performs addition of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x + y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_plus(VALUE x, VALUE y);
/**
* Performs subtraction of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x - y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_minus(VALUE x, VALUE y);
/**
* Performs multiplication of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x * y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_mul(VALUE x, VALUE y);
/**
* Performs division of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x / y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_div(VALUE x, VALUE y);
/**
* Performs "integer division". This is different from rb_big_div().
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x.div y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_idiv(VALUE x, VALUE y);
/**
* Performs modulo of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x % y` evaluates to.
* @see rb_num_coerce_bin()
*
* @internal
*
* There also is `rb_big_remainder()` internally, which is different from this
* one.
*/
VALUE rb_big_modulo(VALUE x, VALUE y);
/**
* Performs "divmod" operation. The operation in bignum's context is that it
* calculates rb_big_idiv() and rb_big_modulo() at once.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x.divmod y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_big_divmod(VALUE x, VALUE y);
/**
* Raises `x` to the powerof `y`.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x ** y` evaluates to.
* @see rb_num_coerce_bin()
* @note This can return an instance of ::rb_cFloat, even when both `x`
* and `y` are bignums. Or an instance of ::rb_cRational, when for
* instance `y` is negative.
*/
VALUE rb_big_pow(VALUE x, VALUE y);
/**
* Performs bitwise and of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x & y` evaluates to.
* @see rb_num_coerce_bit()
*/
VALUE rb_big_and(VALUE x, VALUE y);
/**
* Performs bitwise or of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x | y` evaluates to.
* @see rb_num_coerce_bit()
*/
VALUE rb_big_or(VALUE x, VALUE y);
/**
* Performs exclusive or of the passed two objects.
*
* @param[in] x A bignum.
* @param[in] y Arbitrary ruby object.
* @return What `x ^ y` evaluates to.
* @see rb_num_coerce_bit()
*/
VALUE rb_big_xor(VALUE x, VALUE y);
/**
* Performs shift left.
*
* @param[in] x A bignum.
* @param[in] y Shift amount.
* @exception rb_eTypeError `y` is not an integer.
* @exception rb_eArgError `y` is too big.
* @return `x` shifted left to `y` bits.
* @note `y` can be negative. Shifts right then.
*/
VALUE rb_big_lshift(VALUE x, VALUE y);
/**
* Performs shift right.
*
* @param[in] x A bignum.
* @param[in] y Shift amount.
* @exception rb_eTypeError `y` is not an integer.
* @return `x` shifted right to `y` bits.
* @note This is arithmetic. Because bignums are not bitfields there is
* no shift right logical operator.
*/
VALUE rb_big_rshift(VALUE x, VALUE y);
/**
* @name Flags for rb_integer_pack()/rb_integer_unpack()
* @{
*/
/** Stores/interprets the most significant word as the first word. */
#define INTEGER_PACK_MSWORD_FIRST 0x01
/** Stores/interprets the least significant word as the first word. */
#define INTEGER_PACK_LSWORD_FIRST 0x02
/**
* Stores/interprets the most significant byte in a word as the first byte in
* the word.
*/
#define INTEGER_PACK_MSBYTE_FIRST 0x10
/**
* Stores/interprets the least significant byte in a word as the first byte in
* the word.
*/
#define INTEGER_PACK_LSBYTE_FIRST 0x20
/**
* Means either #INTEGER_PACK_MSBYTE_FIRST or #INTEGER_PACK_LSBYTE_FIRST,
* depending on the host processor's endian.
*/
#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
/** Uses 2's complement representation. */
#define INTEGER_PACK_2COMP 0x80
/** Uses "generic" implementation (handy on test). */
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
/**
* Always generates a bignum object even if the integer can be representable
* using fixnum scheme (unpack only)
*/
#define INTEGER_PACK_FORCE_BIGNUM 0x100
/**
* Interprets the input as a signed negative number (unpack only). If not
* specified returns a positive number.
*/
#define INTEGER_PACK_NEGATIVE 0x200
/** Little endian combination. */
#define INTEGER_PACK_LITTLE_ENDIAN \
(INTEGER_PACK_LSWORD_FIRST | \
INTEGER_PACK_LSBYTE_FIRST)
/** Big endian combination */
#define INTEGER_PACK_BIG_ENDIAN \
(INTEGER_PACK_MSWORD_FIRST | \
INTEGER_PACK_MSBYTE_FIRST)
/** @} */
RBIMPL_ATTR_NONNULL(())
/**
* Exports an integer into a buffer. This function fills the buffer specified
* by `words` and `numwords` as `val` in the format specified by `wordsize`,
* `nails` and `flags`.
*
* @param[in] val Integer or integer-like object which has
* `#to_int` method.
* @param[out] words Return buffer.
* @param[in] numwords Number of words of `words`.
* @param[in] wordsize Number of bytes per word.
* @param[in] nails Number of padding bits in a word. Most
* significant nails bits of each word are filled
* by zero.
* @param[in] flags Bitwise or of constants whose name starts
* "INTEGER_PACK_".
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
*
* Possible flags are:
*
* - #INTEGER_PACK_MSWORD_FIRST:
* Stores the most significant word as the first word.
*
* - #INTEGER_PACK_LSWORD_FIRST:
* Stores the least significant word as the first word.
*
* - #INTEGER_PACK_MSBYTE_FIRST:
* Stores the most significant byte in a word as the first byte in the
* word.
*
* - #INTEGER_PACK_LSBYTE_FIRST:
* Stores the least significant byte in a word as the first byte in the
* word.
*
* - #INTEGER_PACK_NATIVE_BYTE_ORDER:
* Either #INTEGER_PACK_MSBYTE_FIRST or #INTEGER_PACK_LSBYTE_FIRST
* corresponding to the host's endian.
*
* - #INTEGER_PACK_2COMP:
* Uses 2's complement representation.
*
* - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
* `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`.
*
* - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
* `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`.
*
* - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
* Uses generic implementation (for test and debug).
*
* This function fills the buffer specified by `words` as `val`'s 2's
* complement representation if #INTEGER_PACK_2COMP is specified in `flags`.
* Otherwise it fills `words` as `abs(val)` and signedness is returned via the
* return value.
*
* @return The signedness and overflow condition. The overflow condition
* depends on #INTEGER_PACK_2COMP.
*
* When #INTEGER_PACK_2COMP is not specified:
*
* - `-2` :
* Negative overflow. `val <= -2**(numwords*(wordsize*CHAR_BIT-nails))`
*
* - `-1` :
* Negative without overflow.
* `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0`
*
* - `0` : zero. `val == 0`
*
* - `1` :
* Positive without overflow.
* `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
*
* - `2` :
* Positive overflow. `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
*
* When #INTEGER_PACK_2COMP is specified:
*
* - `-2` :
* Negative overflow. `val < -2**(numwords*(wordsize*CHAR_BIT-nails))`
*
* - `-1` :
* Negative without overflow.
* `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0`
*
* - `0` : zero. `val == 0`
*
* - `1` :
* Positive without overflow.
* `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
*
* - `2` :
* Positive overflow. `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
*
* The value, `-2**(numwords*(wordsize*CHAR_BIT-nails))`, is representable in
* 2's complement representation but not representable in absolute value. So
* `-1` is returned for the value if #INTEGER_PACK_2COMP is specified but
* returns `-2` if #INTEGER_PACK_2COMP is not specified.
*
* The least significant words are filled in the buffer when overflow occur.
*/
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
RBIMPL_ATTR_NONNULL(())
/**
* Import an integer from a buffer.
*
* @param[in] words Buffer to import.
* @param[in] numwords Number of words of `words`.
* @param[in] wordsize Number of bytes per word.
* @param[in] nails Number of padding bits in a word. Most
* significant nails bits of each word are ignored.
* @param[in] flags Bitwise or of constants whose name starts
* "INTEGER_PACK_".
* @exception rb_eArgError `numwords * wordsize` too big.
*
* Possible flags are:
*
* - #INTEGER_PACK_MSWORD_FIRST:
* Interpret the first word as the most significant word.
*
* - #INTEGER_PACK_LSWORD_FIRST:
* Interpret the first word as the least significant word.
*
* - #INTEGER_PACK_MSBYTE_FIRST:
* Interpret the first byte in a word as the most significant byte in the
* word.
*
* - #INTEGER_PACK_LSBYTE_FIRST:
* Interpret the first byte in a word as the least significant byte in
* the word.
*
* - #INTEGER_PACK_NATIVE_BYTE_ORDER:
* Either #INTEGER_PACK_MSBYTE_FIRST or #INTEGER_PACK_LSBYTE_FIRST
* corresponding to the host's endian.
*
* - #INTEGER_PACK_2COMP:
* Uses 2's complement representation.
*
* - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
* `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`
*
* - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
* `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`
*
* - #INTEGER_PACK_FORCE_BIGNUM:
* Returns a bignum even if its value is representable as a fixnum.
*
* - #INTEGER_PACK_NEGATIVE:
* Returns a non-positive value. (Returns a non-negative value if not
* specified.)
*
* - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
* Uses generic implementation (for test and debug).
*
* @return An instance of ::rb_cInteger whose value is the interpreted
* `words`. The range of the result value depends on
* #INTEGER_PACK_2COMP and #INTEGER_PACK_NEGATIVE.
*
* When #INTEGER_PACK_2COMP is not set:
*
* - `0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails))` if
* `!INTEGER_PACK_NEGATIVE`
*
* - `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0` if
* `INTEGER_PACK_NEGATIVE`
*
* When #INTEGER_PACK_2COMP is set:
*
* - `-2**(numwords*(wordsize*CHAR_BIT-nails)-1)` `<= val <=`
* `2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1` if
* `!INTEGER_PACK_NEGATIVE`
*
* - `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1` if
* `INTEGER_PACK_NEGATIVE`
*
* Passing #INTEGER_PACK_2COMP without #INTEGER_PACK_NEGATIVE means sign
* extension. #INTEGER_PACK_2COMP with #INTEGER_PACK_NEGATIVE means assuming
* the higher bits are `1`.
*
* Note that this function returns 0 when `numwords` is zero and
* #INTEGER_PACK_2COMP is set but #INTEGER_PACK_NEGATIVE is not set.
*/
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
/**
* Calculates the number of bytes needed to represent the absolute value of the
* passed integer.
*
* @param[in] val Integer or integer-like object which has
* `#to_int` method.
* @param[out] nlz_bits_ret Number of leading zero bits in the most
* significant byte is returned if not `NULL`.
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
* @return `((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)`, where
* val_numbits is the number of bits of `abs(val)`.
* @post If `nlz_bits_ret` is not `NULL`,
* `(return_value * CHAR_BIT - val_numbits)` is stored in
* `*nlz_bits_ret`. In this case,
* `0 <= *nlz_bits_ret < CHAR_BIT`.
*
* This function should not overflow.
*/
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
/**
* Calculates the number of words needed represent the absolute value of the
* passed integer. Unlike rb_absint_size() this function can overflow. It
* returns `(size_t)-1` then.
*
* @param[in] val Integer or integer-like object which has
* `#to_int` method.
* @param[in] word_numbits Number of bits per word.
* @param[out] nlz_bits_ret Number of leading zero bits in the most
* significant word is returned if not `NULL`.
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
* @retval (size_t)-1 Overflowed.
* @retval otherwise
`((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)`,
* where val_numbits is the number of bits of `abs(val)`.
* @post If `nlz_bits_ret` is not `NULL` and there is no overflow,
* `(return_value * word_numbits - val_numbits)` is stored in
* `*nlz_bits_ret`. In this case,
* `0 <= *nlz_bits_ret < word_numbits.`
*
*/
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
/**
* Tests `abs(val)` consists only of a bit or not.
*
* @param[in] val Integer or integer-like object which has
* `#to_int` method.
* @exception rb_eTypeError `val` doesn't respond to `#to_int`.
* @retval 1 `abs(val) == 1 << n` for some `n >= 0`.
* @retval 0 Otherwise.
*
* rb_absint_singlebit_p() can be used to determine required buffer size for
* rb_integer_pack() used with #INTEGER_PACK_2COMP (two's complement).
*
* Following example calculates number of bits required to represent val in
* two's complement number, without sign bit.
*
* ```CXX
* size_t size;
* int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
* size = rb_absint_numwords(val, 1, NULL)
* if (size == (size_t)-1) ...overflow...
* if (neg && rb_absint_singlebit_p(val))
* size--;
* ```
*
* Following example calculates number of bytes required to represent val in
* two's complement number, with sign bit.
*
* ```CXX
* size_t size;
* int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
* int nlz_bits;
* size = rb_absint_size(val, &nlz_bits);
* if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
* size++;
* ```
*/
int rb_absint_singlebit_p(VALUE val);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_BIGNUM_H */
include/ruby/internal/intern/array.h 0000644 00000062233 15040330603 0013552 0 ustar 00 #ifndef RBIMPL_INTERN_ARRAY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ARRAY_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cArray.
*/
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/noexcept.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* array.c */
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
* Fills the memory region with a series of ::RUBY_Qnil.
*
* @param[out] buf Buffer to squash.
* @param[in] len Number of objects of `buf`.
* @post `buf` is filled with ::RUBY_Qnil.
*/
void rb_mem_clear(VALUE *buf, long len)
RBIMPL_ATTR_NOEXCEPT(true)
;
/**
* Identical to rb_ary_new_from_values(), except it expects exactly two
* parameters.
*
* @param[in] car Arbitrary ruby object.
* @param[in] cdr Arbitrary ruby object.
* @return An allocated new array, of length 2, whose contents are the
* passed objects.
*/
VALUE rb_assoc_new(VALUE car, VALUE cdr);
/**
* Try converting an object to its array representation using its `to_ary`
* method, if any. If there is no such thing, returns ::RUBY_Qnil.
*
* @param[in] obj Arbitrary ruby object to convert.
* @exception rb_eTypeError `obj.to_ary` returned something non-Array.
* @retval RUBY_Qnil No conversion from `obj` to array defined.
* @retval otherwise Converted array representation of `obj`.
* @see rb_io_check_io
* @see rb_check_string_type
* @see rb_check_hash_type
*/
VALUE rb_check_array_type(VALUE obj);
/**
* Allocates a new, empty array.
*
* @return An allocated new array, whose length is 0.
*/
VALUE rb_ary_new(void);
/**
* Identical to rb_ary_new(), except it additionally specifies how many rooms
* of objects it should allocate. This way you can create an array whose
* capacity is bigger than the length of it. If you can say that an array
* grows to a specific amount, this could be effective than resizing an array
* over and over again and again.
*
* @param[in] capa Designed capacity of the generating array.
* @return An empty array, whose capacity is `capa`.
*/
VALUE rb_ary_new_capa(long capa);
/**
* Constructs an array from the passed objects.
*
* @param[in] n Number of passed objects.
* @param[in] ... Arbitrary ruby objects, filled into the returning array.
* @return An array of size `n`, whose contents are the passed objects.
*/
VALUE rb_ary_new_from_args(long n, ...);
/**
* Identical to rb_ary_new_from_args(), except how objects are passed.
*
* @param[in] n Number of objects of `elts`.
* @param[in] elts Arbitrary ruby objects, filled into the returning array.
* @return An array of size `n`, whose contents are the passed objects.
*/
VALUE rb_ary_new_from_values(long n, const VALUE *elts);
/**
* Allocates a hidden (no class) empty array.
*
* @param[in] capa Designed capacity of the array.
* @return A hidden, empty array.
* @see rb_obj_hide()
*/
VALUE rb_ary_hidden_new(long capa);
#define rb_ary_tmp_new rb_ary_hidden_new
/**
* Destroys the given array for no reason.
*
* @warning DO NOT USE IT.
* @warning Leave this task to our GC.
* @warning It was a wrong indea at the first place to let you know about it.
*
* @param[out] ary The array to be executed.
* @post The given array no longer exists.
* @note Maybe `Array#clear` could be what you want.
*
* @internal
*
* Should have moved this to `internal/array.h`.
*/
void rb_ary_free(VALUE ary);
/**
* Declares that the array is about to be modified. This for instance let the
* array have a dedicated backend storage.
*
* @param[out] ary Array about to be modified.
* @exception rb_eFrozenError `ary` is frozen.
* @post Upon successful return the passed array is eligible to be
* modified.
*/
void rb_ary_modify(VALUE ary);
/** @alias{rb_obj_freeze} */
VALUE rb_ary_freeze(VALUE obj);
RBIMPL_ATTR_PURE()
/**
* Queries if the passed two arrays share the same backend storage. A use-case
* for knowing such property is to take a snapshot of an array (using
* e.g. rb_ary_replace()), then check later if that snapshot still shares the
* storage with the original. Taking a snapshot is ultra-cheap. If nothing
* happens the impact shall be minimal. But if someone modifies the original,
* that entity shall pay the cost of copy-on-write. You can detect that using
* this API.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval RUBY_Qtrue They share the same backend storage.
* @retval RUBY_Qfalse They are distinct.
* @pre Both arguments must be of ::RUBY_T_ARRAY.
*/
VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs);
/**
* Queries element(s) of an array. This is complicated! Refer `Array#slice`
* document for the complete description of how it behaves.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Up to 2 objects.
* @param[in] ary Target array.
* @exception rb_eTypeError `argv` (or its part) includes non-Integer.
* @exception rb_eRangeError rb_cArithSeq is passed, and is OOB.
* @return An element (if requested), or an array of elements (if
* requested), or ::RUBY_Qnil (if index OOB).
*
* @internal
*
* ```rbs
* # "int" is ::Integer or `#to_int`, defined in builtin.rbs
*
* class ::Array[unchecked out T]
* def slice
* : (int i) -> T?
* | (int beg, int len) -> ::Array[T]?
* | (Range[int] r) -> ::Array[T]?
* | (ArithmeticSequence as) -> ::Array[T]? # This also raises RagneError.
* end
* ```
*/
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary);
/**
* Obtains a part of the passed array.
*
* @param[in] ary Target array.
* @param[in] beg Subpart index.
* @param[in] len Requested length of returning array.
* @retval RUBY_Qnil Requested range out of bounds of `ary`.
* @retval otherwise An allocated new array whose contents are `ary`'s
* `beg` to `len`.
* @note Return array can be shorter than `len` when for instance
* `[0, 1, 2, 3]`'s 4th to 1,000,000,000th is requested.
*/
VALUE rb_ary_subseq(VALUE ary, long beg, long len);
/**
* Destructively stores the passed value to the passed array's passed index.
* It also resizes the array's backend storage so that the requested index is
* not out of bounds.
*
* @param[out] ary Target array to modify.
* @param[in] key Where to store `val`.
* @param[in] val What to store at `key`.
* @exception rb_eFrozenError `ary` is frozen.
* @exception rb_eIndexError `key` is negative.
* @post `ary`'s `key`th position is occupied with `val`.
* @post Depending on `key` and previous length of `ary` this operation
* can also create a series of "hole" positions inside of the
* backend storage. They are filled with ::RUBY_Qnil.
*/
void rb_ary_store(VALUE ary, long key, VALUE val);
/**
* Duplicates an array.
*
* @param[in] ary Target to duplicate.
* @return An allocated new array whose contents are identical to `ary`.
*
* @internal
*
* Not sure why this has to be something different from `ary_make_shared_copy`,
* which seems much efficient.
*/
VALUE rb_ary_dup(VALUE ary);
/**
* I guess there is no use case of this function in extension libraries, but
* this is a routine identical to rb_ary_dup(). This makes the most sense when
* the passed array is formerly hidden by rb_obj_hide().
*
* @param[in] ary An array, possibly hidden.
* @return A duplicated new instance of ::rb_cArray.
*/
VALUE rb_ary_resurrect(VALUE ary);
/**
* Force converts an object to an array. It first tries its `#to_ary` method.
* Takes the result if any. Otherwise creates an array of size 1 whose sole
* element is the passed object.
*
* @param[in] obj Arbitrary ruby object.
* @return An array representation of `obj`.
* @note Unlike rb_str_to_str() which is a variant of
* rb_check_string_type(), rb_ary_to_ary() is not a variant of
* rb_check_array_type().
*/
VALUE rb_ary_to_ary(VALUE obj);
/**
* Converts an array into a human-readable string. Historically its behaviour
* changed over time. Currently it is identical to calling `inspect` method.
* This behaviour is from that of python (!!) circa 2006.
*
* @param[in] ary Array to inspect.
* @return Recursively inspected representation of `ary`.
* @see `[ruby-dev:29520]`
*/
VALUE rb_ary_to_s(VALUE ary);
/**
* Destructively appends multiple elements at the end of the array.
*
* @param[out] ary Where to push `train`.
* @param[in] train Arbitrary ruby objects to push to `ary`.
* @param[in] len Number of objects of `train`.
* @exception rb_eIndexError `len` too large.
* @exception rb_eFrozenError `ary` is frozen.
* @return The passed `ary`.
* @post `ary` has contents from `train` appended at its end.
*/
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len);
/**
* Special case of rb_ary_cat() that it adds only one element.
*
* @param[out] ary Where to push `elem`.
* @param[in] elem Arbitrary ruby object to push.
* @exception rb_eFrozenError `ary` is frozen.
* @return The passed `ary`.
* @post `ary` has `elem` appended at its end.
*/
VALUE rb_ary_push(VALUE ary, VALUE elem);
/**
* Destructively deletes an element from the end of the passed array and
* returns what was deleted.
*
* @param[out] ary Target array to modify.
* @exception rb_eFrozenError `ary` is frozen.
* @return What was at the end of `ary`, or ::RUBY_Qnil if there is
* nothing to remove.
* @post `ary`'s last element, if any, is removed.
* @note There is no way to distinguish whether `ary` was an 1-element
* array whose content was ::RUBY_Qnil, or was empty.
*/
VALUE rb_ary_pop(VALUE ary);
/**
* Destructively deletes an element from the beginning of the passed array and
* returns what was deleted. It can also be seen as a routine identical to
* rb_ary_pop(), except which side of the array to scrub.
*
* @param[out] ary Target array to modify.
* @exception rb_eFrozenError `ary` is frozen.
* @return What was at the beginning of `ary`, or ::RUBY_Qnil if there is
* nothing to remove.
* @post `ary`'s first element, if any, is removed. As the name implies
* everything else remaining in `ary` gets moved towards `ary`'s
* beginning.
* @note There is no way to distinguish whether `ary` was an 1-element
* array whose content was ::RUBY_Qnil, or was empty.
*/
VALUE rb_ary_shift(VALUE ary);
/**
* Destructively prepends the passed item at the beginning of the passed array.
* It can also be seen as a routine identical to rb_ary_push(), except which
* side of the array to modify.
*
* @param[out] ary Target array to modify.
* @param[in] elem Arbitrary ruby object to unshift.
* @exception rb_eFrozenError `ary` is frozen.
* @return The passed `ary`.
* @post `ary` has `elem` prepended at this beginning.
*/
VALUE rb_ary_unshift(VALUE ary, VALUE elem);
RBIMPL_ATTR_PURE()
/**
* Queries an element of an array. When passed offset is negative it counts
* backwards.
*
* @param[in] ary An array to look into.
* @param[in] off Offset (can be negative).
* @return ::RUBY_Qnil when `off` is out of bounds of `ary`. Otherwise
* what is stored at `off`-th position of `ary`.
* @note `ary`'s `off`-th element can happen to be ::RUBY_Qnil.
*/
VALUE rb_ary_entry(VALUE ary, long off);
/**
* Iteratively yields each element of the passed array to the implicitly passed
* block if any. In case there is no block given, an enumerator that does the
* thing is generated instead.
*
* @param[in] ary Array to iterate over.
* @retval ary Passed block was evaluated.
* @retval otherwise An instance of ::rb_cEnumerator for `Array#each`.
*/
VALUE rb_ary_each(VALUE ary);
/**
* Recursively stringises the elements of the passed array, flattens that
* result, then joins the sequence using the passed separator.
*
* @param[in] ary Target array to convert.
* @param[in] sep Separator. Either a string, or ::RUBY_Qnil
* if you want no separator.
* @exception rb_eArgError Infinite recursion in `ary`.
* @exception rb_eTypeError `sep` is not a string.
* @exception rb_eEncCompatError Strings do not agree with their encodings.
* @return An instance of ::rb_cString which concatenates stringised
* contents of `ary`, using `sep` as separator.
*/
VALUE rb_ary_join(VALUE ary, VALUE sep);
/**
* _Destructively_ reverses the passed array in-place.
*
* @warning This is `Array#reverse!`, not `Array#reverse`.
* @param[out] ary Target array to modify.
* @exception rb_eFrozenError `ary` is frozen.
* @return Passed `ary`.
* @post `ary` is reversed.
*/
VALUE rb_ary_reverse(VALUE ary);
/**
* _Destructively_ rotates the passed array in-place to towards its end. The
* amount can be negative. Would rotate to the opposite direction then.
*
* @warning This is `Array#rotate!`, not `Array#rotate`.
* @param[out] ary Target array to modify.
* @param[in] rot Amount of rotation.
* @exception rb_eFrozenError `ary` is frozen.
* @retval RUBY_Qnil Not rotated.
* @retval ary Rotated.
* @post `ary` is rotated.
*/
VALUE rb_ary_rotate(VALUE ary, long rot);
/**
* Creates a copy of the passed array, whose elements are sorted according to
* their `<=>` result.
*
* @param[in] ary Array to sort.
* @exception rb_eArgError Comparison not defined among elements.
* @exception rb_eRuntimeError Infinite recursion in `<=>`.
* @return A copy of `ary`, sorted.
* @note As of writing this function uses `qsort` as backend algorithm,
* which means the result is unstable (in terms of sort stability).
*/
VALUE rb_ary_sort(VALUE ary);
/**
* Destructively sorts the passed array in-place, according to each elements'
* `<=>` result.
*
* @param[in] ary Target array to modify.
* @exception rb_eArgError Comparison not defined among elements.
* @exception rb_eRuntimeError Infinite recursion in `<=>`.
* @return Passed `ary`.
* @post `ary` is sorted.
* @note As of writing this function uses `qsort` as backend algorithm,
* which means the result is unstable (in terms of sort stability).
*/
VALUE rb_ary_sort_bang(VALUE ary);
/**
* Destructively removes elements from the passed array, so that there would be
* no elements inside that satisfy `==` relationship with the passed object.
* Returns the last deleted element if any. But in case there was nothing to
* delete it gets complicated. It checks for the implicitly passed block. If
* there is a block the return value would be what the block evaluates to.
* Otherwise it resorts to ::RUBY_Qnil.
*
* @param[out] ary Target array to modify.
* @param[in] elem Template object to match against each element.
* @exception rb_eFrozenError `ary` is frozen.
* @return What was deleted, or what was the block returned, or
* ::RUBY_Qnil (see above).
* @post All elements that have `==` relationship with `elem` are purged
* from `ary`. Elements shift their positions so that `ary` gets
* compact.
*
* @internal
*
* Internally there also is `rb_ary_delete_same`, which compares by identity.
*/
VALUE rb_ary_delete(VALUE ary, VALUE elem);
/**
* Destructively removes an element which resides at the specific index of the
* passed array. Unlike rb_ary_stre() the index can be negative, which means
* the index counts backwards from the array's tail.
*
* @param[out] ary Target array to modify.
* @param[in] pos Position (can be negative).
* @exception rb_eFrozenError `ary` is frozen.
* @return What was deleted, or ::RUBY_Qnil in case of OOB.
* @post `ary`'s `pos`-th element is deleted if any.
* @note There is no way to distinguish whether `pos` is out of bound,
* or `pos` did exist but stored ::RUBY_Qnil as an ordinal value.
*/
VALUE rb_ary_delete_at(VALUE ary, long pos);
/**
* Destructively removes everything form an array.
*
* @param[out] ary Target array to modify.
* @exception rb_eFrozenError `ary` is frozen.
* @return The passed `ary`.
* @post `ary` is an empty array.
*/
VALUE rb_ary_clear(VALUE ary);
/**
* Creates a new array, concatenating the former to the latter.
*
* @param[in] lhs Source array #1.
* @param[in] rhs Source array #2.
* @exception rb_eIndexError Result array too big.
* @return A new array containing `rhs` concatenated to `lhs`.
* @note This operation doesn't commute. Don't get confused by the
* "plus" terminology. For historical reasons there are some
* noncommutative `+`s in Ruby. This is one of such things. There
* has been a long discussion around `+`s in programming languages.
*
* @internal
*
* rb_ary_concat() is not a destructive version of rb_ary_plus(). They raise
* different exceptions. Don't know why though.
*/
VALUE rb_ary_plus(VALUE lhs, VALUE rhs);
/**
* Destructively appends the contents of latter into the end of former.
*
* @param[out] lhs Destination array.
* @param[in] rhs Source array.
* @exception rb_eFrozenError `lhs` is frozen.
* @exception rb_eIndexError Result array too big.
* @exception rb_eTypeError `rhs` doesn't respond to `#to_ary`.
* @return The passed `lhs`.
* @post `lhs` has contents of `rhs` appended to its end.
*/
VALUE rb_ary_concat(VALUE lhs, VALUE rhs);
/**
* Looks up the passed key, assuming the passed array is an alist. An "alist"
* here is a list of "association"s, much like that of Emacs. Emacs has
* `assoc` function that behaves exactly the same as this one.
*
* ```ruby
* # This is an example of aliist.
* auto_mode_alist = [
* [ /\.[ch]\z/, :"c-mode" ],
* [ /\.[ch]pp\z/, :"c++-mode" ],
* [ /\.awk\z/, :"awk-mode" ],
* [ /\.cs\z/, :"csharp-mode" ],
* [ /\.go\z/, :"go-mode" ],
* [ /\.java\z/, :"java-mode" ],
* [ /\.pas\z/, :"pascal-mode" ],
* [ /\.rs\z/, :"rust-mode" ],
* [ /\.txt\z/, :"text-mode" ],
* ]
* ```
*
* This function scans the passed array looking for an element, which itself is
* an array, whose first element is the passed key. If no such element is
* found, returns ::RUBY_Qnil.
*
* Although this function expects the passed array be an array of arrays, it
* can happily accept non-array elements; it just ignores such things.
*
* @param[in] alist An array of arrays.
* @param[in] key Needle.
* @retval RUBY_Qnil Nothing was found.
* @retval otherwise An element in `alist` whose first element is in `==`
* relationship with `key`.
*/
VALUE rb_ary_assoc(VALUE alist, VALUE key);
/**
* Identical to rb_ary_assoc(), except it scans the passed array from the
* opposite direction.
*
* @param[in] alist An array of arrays.
* @param[in] key Needle.
* @retval RUBY_Qnil Nothing was found.
* @retval otherwise An element in `alist` whose first element is in `==`
* relationship with `key`.
*/
VALUE rb_ary_rassoc(VALUE alist, VALUE key);
/**
* Queries if the passed array has the passed entry.
*
* @param[in] ary Target array to scan.
* @param[in] elem Target array to find.
* @retval RUBY_Qfalse No element in `ary` is in `==` relationship with
* `elem`.
* @retval RUBY_Qtrue There is at least one element in `ary` which is in
* `==` relationship with `elem`.
*
* @internal
*
* This is the only function in the entire C API that is named using third
* person singular form of a verb (except #ISASCII etc., which are not our
* naming). The counterpart Ruby API of this function is `Array#include?`.
*/
VALUE rb_ary_includes(VALUE ary, VALUE elem);
/**
* Recursively compares each elements of the two arrays one-by-one using `<=>`.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval RUBY_Qnil `lhs` and `rhs` are not comparable.
* @retval -1 `lhs` is less than `rhs`.
* @retval 0 They are equal.
* @retval 1 `rhs` is less then `lhs`.
*/
VALUE rb_ary_cmp(VALUE lhs, VALUE rhs);
/**
* Replaces the contents of the former object with the contents of the latter.
*
* @param[out] copy Destination object.
* @param[in] orig Source object.
* @exception rb_eTypeError `orig` has no implicit conversion to Array.
* @exception rb_eFrozenError `copy` is frozen.
* @return The passed `copy`.
* @post `copy`'s former components are abandoned. It now has the
* identical length and contents to `orig`.
*/
VALUE rb_ary_replace(VALUE copy, VALUE orig);
/**
* This _was_ a generalisation of `Array#values_at`, `Struct#values_at`, and
* `MatchData#values_at`. It begun its life as a refactoring effort. However
* as Ruby evolves over time, as of writing none of aforementioned methods
* share their implementations at all. This function is not deprecated; still
* works as it has been. But it is now kind of like a rudimentum.
*
* This function takes an object, which is a receiver, and a series of
* "indices", which are either integers, or ranges of integers. Calls the
* passed callback for each of those indices, along with the receiver. This
* callback is expected to do something like rb_ary_aref(), rb_struct_aref(),
* etc. In case of a range index rb_range_beg_len() expands the range.
* Finally return values of the callback are gathered as an array, then
* returned.
*
* @param[in] obj Arbitrary ruby object.
* @param[in] olen "Length" of `obj`.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv List of "indices", described above.
* @param[in] func Callback function.
* @return A new instance of ::rb_cArray gathering `func`outputs.
*
* @internal
*
* `Array#values_at` no longer uses this function. There is no reason apart
* from historical ones to list this function here.
*/
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func)(VALUE obj, long oidx));
/**
* Expands or shrinks the passed array to the passed length.
*
* @param[out] ary An array to modify.
* @param[in] len Desired length of `ary`.
* @exception rb_eFrozenError `ary` is frozen.
* @exception rb_eIndexError `len` too long.
* @return The passed `ary`.
* @post `ary`'s length is `len`.
* @post Depending on `len` and previous length of `ary` this operation
* can also create a series of "hole" positions inside of the
* backend storage. They are filled with ::RUBY_Qnil.
*
* @internal
*
* `len` is signed. Intentional or...?
*/
VALUE rb_ary_resize(VALUE ary, long len);
#define rb_ary_new2 rb_ary_new_capa /**< @old{rb_ary_new_capa} */
#define rb_ary_new3 rb_ary_new_from_args /**< @old{rb_ary_new_from_args} */
#define rb_ary_new4 rb_ary_new_from_values /**< @old{rb_ary_new_from_values} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_ARRAY_H */
include/ruby/internal/intern/marshal.h 0000644 00000012712 15040330603 0014060 0 ustar 00 #ifndef RBIMPL_INTERN_MARSHAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_MARSHAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to rb_mMarshal.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* marshal.c */
/**
* Serialises the given object and all its referring objects, to write them
* down to the passed port.
*
* @param[in] obj Target object to dump.
* @param[out] port IO-like destination buffer.
* @exception rb_eTypeError `obj` cannot be dumped for some reason.
* @exception rb_eRuntimeError `obj` was tampered during dumping.
* @exception rb_eArgError Traversal too deep.
* @return The passed `port` as-is.
* @post Serialised representation of `obj` is written to `port`.
* @note `port` is basically an IO but StringIO is also possible.
*/
VALUE rb_marshal_dump(VALUE obj, VALUE port);
/**
* Deserialises a previous output of rb_marshal_dump() into a network of
* objects.
*
* @param[in,out] port Either IO or String.
* @exception rb_eTypeError `port` is in unexpected type.
* @exception rb_eArgError Contents of `port` is broken.
* @return Object(s) rebuilt using the info from `port`.
*
* SECURITY CONSIDERATIONS
* ========================
*
* @warning By design, rb_marshal_load() can deserialise almost any
* class loaded into the Ruby process. In many cases this can
* lead to remote code execution if the Marshal data is loaded
* from an untrusted source.
* @warning As a result, rb_marshal_load() is not suitable as a general
* purpose serialisation format and you should never unmarshal
* user supplied input or other untrusted data.
* @warning If you need to deserialise untrusted data, use JSON or
* another serialisation format that is only able to load
* simple, 'primitive' types such as String, Array, Hash, etc.
* Never allow user input to specify arbitrary types to
* deserialise into.
*/
VALUE rb_marshal_load(VALUE port);
/**
* Marshal format compatibility layer. Over time, classes evolve, so that
* their internal data structure change drastically. For instance an instance
* of ::rb_cRange was made of ::RUBY_T_OBJECT in 1.x., but in 3.x it is a
* ::RUBY_T_STRUCT now. In order to keep binary compatibility, we "fake" the
* marshalled representation to stick to old types. This is the API to enable
* that manoeuvre. Here is how:
*
* First, because you are going to keep backwards compatibility, you need to
* retain the old implementation of your class. Rename it, and keep the class
* somewhere (for instance rb_register_global_address() could help). Next
* create your new class. Do whatever you want.
*
* Then, this is the key point. Create two new "bridge" functions that convert
* the structs back and forth:
*
* - the "dumper" function that takes an instance of the new class, and
* returns an instance of the old one. This is called from
* rb_marshal_dump(), to keep it possible for old programs to read your new
* data.
*
* - the "loader" function that takes two arguments, new one and old one, in
* that order. rb_marshal_load() calls this function when it finds a
* representation of the retained old class. The old one passed to this
* function is the reconstructed instance of the old class.
* Reverse-engineer that to modify the new one, to have the identical
* contents.
*
* Finally, connect all of them using this function.
*
* @param[in] newclass The class that needs conversion.
* @param[in] oldclass Old implementation of `newclass`.
* @param[in] dumper Function that converts `newclass` to `oldclass`.
* @param[in] loader Function that converts `oldclass` to `newclass`.
* @exception rb_eTypeError `newclass` has no allocator.
*/
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_MARSHAL_H */
include/ruby/internal/intern/complex.h 0000644 00000020326 15040330603 0014100 0 ustar 00 #ifndef RBIMPL_INTERN_COMPLEX_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_COMPLEX_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cComplex.
*/
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* complex.c */
/**
* Identical to rb_complex_new(), except it assumes both arguments are not
* instances of ::rb_cComplex. It is thus dangerous for extension libraries.
*
* @param[in] real Real part, in any numeric except Complex.
* @param[in] imag Imaginary part, in any numeric except Complex.
* @return An instance of ::rb_cComplex whose value is `real + (imag)i`.
*/
VALUE rb_complex_raw(VALUE real, VALUE imag);
/**
* Shorthand of `x+0i`. It practically converts `x` into a Complex of the
* identical value.
*
* @param[in] x Any numeric except Complex.
* @return An instance of ::rb_cComplex, whose value is `x + 0i`.
*/
#define rb_complex_raw1(x) rb_complex_raw((x), INT2FIX(0))
/** @alias{rb_complex_raw} */
#define rb_complex_raw2(x,y) rb_complex_raw((x), (y))
/**
* Constructs a Complex, by first multiplying the imaginary part with `1i` then
* adds it to the real part. This definition doesn't need both arguments be
* real numbers. It can happily combine two instances of ::rb_cComplex (with
* rotating the latter one).
*
* @param[in] real An instance of ::rb_cNumeric.
* @param[in] imag Another instance of ::rb_cNumeric.
* @return An instance of ::rb_cComplex whose value is `imag * 1i + real`.
*/
VALUE rb_complex_new(VALUE real, VALUE imag);
/**
* Shorthand of `x+0i`. It practically converts `x` into a Complex of the
* identical value.
*
* @param[in] x Any numeric value.
* @return An instance of ::rb_cComplex, whose value is `x + 0i`.
*/
#define rb_complex_new1(x) rb_complex_new((x), INT2FIX(0))
/** @alias{rb_complex_new} */
#define rb_complex_new2(x,y) rb_complex_new((x), (y))
/**
* Constructs a Complex using polar representations. Unlike rb_complex_new()
* it makes no sense to pass non-real instances to this function.
*
* @param[in] abs Magnitude, in any numeric except Complex.
* @param[in] arg Angle, in radians, in any numeric except Complex.
* @return An instance of ::rb_cComplex which denotes the given polar
* coordinates.
*/
VALUE rb_complex_new_polar(VALUE abs, VALUE arg);
RBIMPL_ATTR_DEPRECATED(("by: rb_complex_new_polar"))
/** @old{rb_complex_new_polar} */
VALUE rb_complex_polar(VALUE abs, VALUE arg);
RBIMPL_ATTR_PURE()
/**
* Queries the real part of the passed Complex.
*
* @param[in] z An instance of ::rb_cComplex.
* @return Its real part, which is an instance of ::rb_cNumeric.
*/
VALUE rb_complex_real(VALUE z);
RBIMPL_ATTR_PURE()
/**
* Queries the imaginary part of the passed Complex.
*
* @param[in] z An instance of ::rb_cComplex.
* @return Its imaginary part, which is an instance of ::rb_cNumeric.
*/
VALUE rb_complex_imag(VALUE z);
/**
* Performs addition of the passed two objects.
*
* @param[in] x An instance of ::rb_cComplex.
* @param[in] y Arbitrary ruby object.
* @return What `x + y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_complex_plus(VALUE x, VALUE y);
/**
* Performs subtraction of the passed two objects.
*
* @param[in] x An instance of ::rb_cComplex.
* @param[in] y Arbitrary ruby object.
* @return What `x - y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_complex_minus(VALUE x, VALUE y);
/**
* Performs multiplication of the passed two objects.
*
* @param[in] x An instance of ::rb_cComplex.
* @param[in] y Arbitrary ruby object.
* @return What `x * y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_complex_mul(VALUE x, VALUE y);
/**
* Performs division of the passed two objects.
*
* @param[in] x An instance of ::rb_cComplex.
* @param[in] y Arbitrary ruby object.
* @return What `x / y` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_complex_div(VALUE x, VALUE y);
/**
* Performs negation of the passed object.
*
* @param[in] z An instance of ::rb_cComplex.
* @return What `-z` evaluates to.
*/
VALUE rb_complex_uminus(VALUE z);
/**
* Performs complex conjugation of the passed object.
*
* @param[in] z An instance of ::rb_cComplex.
* @return Its complex conjugate, in ::rb_cComplex.
*/
VALUE rb_complex_conjugate(VALUE z);
/**
* Queries the absolute (or the magnitude) of the passed object.
*
* @param[in] z An instance of ::rb_cComplex.
* @return Its magnitude, in ::rb_cFloat.
*/
VALUE rb_complex_abs(VALUE z);
/**
* Queries the argument (or the angle) of the passed object.
*
* @param[in] z An instance of ::rb_cComplex.
* @return Its magnitude, in ::rb_cFloat.
*/
VALUE rb_complex_arg(VALUE z);
/**
* Performs exponentiation of the passed two objects.
*
* @param[in] base An instance of ::rb_cComplex.
* @param[in] exp Arbitrary ruby object.
* @return What `base ** exp` evaluates to.
* @see rb_num_coerce_bin()
*/
VALUE rb_complex_pow(VALUE base, VALUE exp);
/**
* Identical to rb_complex_new(), except it takes the arguments as C's double
* instead of Ruby's object.
*
* @param[in] real Real part.
* @param[in] imag Imaginary part.
* @return An instance of ::rb_cComplex whose value is `real + (imag)i`.
*/
VALUE rb_dbl_complex_new(double real, double imag);
/** @alias{rb_complex_plus} */
#define rb_complex_add rb_complex_plus
/** @alias{rb_complex_minus} */
#define rb_complex_sub rb_complex_minus
/** @alias{rb_complex_uminus} */
#define rb_complex_nagate rb_complex_uminus
/**
* Converts various values into a Complex. This function accepts:
*
* - Instances of ::rb_cComplex (taken as-is),
* - Instances of ::rb_cNumeric (adds `0i`),
* - Instances of ::rb_cString (parses),
* - Other objects that respond to `#to_c`.
*
* It (possibly recursively) applies `#to_c` until both sides become a Complex
* value, then computes `imag * 1i + real`.
*
* As a special case, passing ::RUBY_Qundef to `imag` is the same as passing
* `RB_INT2NUM(0)`.
*
* @param[in] real Real part (see above).
* @param[in] imag Imaginary part (see above).
* @exception rb_eTypeError Passed something not described above.
* @return An instance of ::rb_cComplex whose value is `1i * imag + real`.
*
* @internal
*
* This was the implementation of `Kernel#Complex` before, but they diverged.
*/
VALUE rb_Complex(VALUE real, VALUE imag);
/**
* Shorthand of `x+0i`. It practically converts `x` into a Complex of the
* identical value.
*
* @param[in] x ::rb_cNumeric, ::rb_cString, or something that responds to
* `#to_c`.
* @return An instance of ::rb_cComplex, whose value is `x + 0i`.
*/
#define rb_Complex1(x) rb_Complex((x), INT2FIX(0))
/** @alias{rb_Complex} */
#define rb_Complex2(x,y) rb_Complex((x), (y))
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_COMPLEX_H */
include/ruby/internal/intern/select/posix.h 0000644 00000010335 15040330603 0015051 0 ustar 00 #ifndef RBIMPL_INTERN_SELECT_POSIX_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_POSIX_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs to provide ::rb_fd_select().
*/
#include "ruby/internal/config.h"
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h> /* for select(2) (modern POSIX) */
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* for select(2) (archaic UNIX) */
#endif
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
/**
* The data structure which wraps the fd_set bitmap used by `select(2)`. This
* allows Ruby to use FD sets larger than what has been historically allowed on
* modern platforms.
*
* @internal
*
* ... but because this header file is included only when the system is with
* that "historic restrictions", this is nothing more than an alias of fd_set.
*/
typedef fd_set rb_fdset_t;
/** Clears the given ::rb_fdset_t. */
#define rb_fd_zero FD_ZERO
/** Sets the given fd to the ::rb_fdset_t. */
#define rb_fd_set FD_SET
/** Unsets the given fd from the ::rb_fdset_t. */
#define rb_fd_clr FD_CLR
/** Queries if the given fd is in the ::rb_fdset_t. */
#define rb_fd_isset FD_ISSET
/** Initialises the :given :rb_fdset_t. */
#define rb_fd_init FD_ZERO
/** Waits for multiple file descriptors at once. */
#define rb_fd_select select
/**@cond INTERNAL_MACRO */
#define rb_fd_copy rb_fd_copy
#define rb_fd_dup rb_fd_dup
#define rb_fd_ptr rb_fd_ptr
#define rb_fd_max rb_fd_max
/** @endcond */
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
* Destructively overwrites an fdset with another.
*
* @param[out] dst Target fdset.
* @param[in] src Source fdset.
* @param[in] n Unused parameter.
* @post `dst` is a copy of `src`.
*/
static inline void
rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n)
{
*dst = *src;
}
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
* Destructively overwrites an fdset with another.
*
* @param[out] dst Target fdset.
* @param[in] src Source fdset.
* @post `dst` is a copy of `src`.
*/
static inline void
rb_fd_dup(rb_fdset_t *dst, const fd_set *src)
{
*dst = *src;
}
RBIMPL_ATTR_PURE()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
* Raw pointer to `fd_set`.
*
* @param[in] f Target fdset.
* @return Underlying fd_set.
*
* @internal
*
* Extension library must not touch raw pointers. It was a bad idea to let
* them use it.
*/
static inline fd_set *
rb_fd_ptr(rb_fdset_t *f)
{
return f;
}
RBIMPL_ATTR_CONST()
/**
* It seems this function has no use. Maybe just remove?
*
* @param[in] f A set.
* @return Number of file descriptors stored.
*/
static inline int
rb_fd_max(const rb_fdset_t *f)
{
return FD_SETSIZE;
}
/** @cond INTERNAL_MACRO */
/* :FIXME: What are these? They don't exist for sibling implementations. */
#define rb_fd_init_copy(d, s) (*(d) = *(s))
#define rb_fd_term(f) ((void)(f))
/** @endcond */
#endif /* RBIMPL_INTERN_SELECT_POSIX_H */
include/ruby/internal/intern/select/largesize.h 0000644 00000015750 15040330603 0015702 0 ustar 00 #ifndef RBIMPL_INTERN_SELECT_LARGESIZE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_LARGESIZE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs to provide ::rb_fd_select().
*
* Several Unix platforms support file descriptors bigger than FD_SETSIZE in
* `select(2)` system call.
*
* - Linux 2.2.12 (?)
*
* - NetBSD 1.2 (src/sys/kern/sys_generic.c:1.25)
* `select(2)` documents how to allocate fd_set dynamically.
* http://netbsd.gw.com/cgi-bin/man-cgi?select++NetBSD-4.0
*
* - FreeBSD 2.2 (src/sys/kern/sys_generic.c:1.19)
*
* - OpenBSD 2.0 (src/sys/kern/sys_generic.c:1.4)
* `select(2)` documents how to allocate fd_set dynamically.
* http://www.openbsd.org/cgi-bin/man.cgi?query=select&manpath=OpenBSD+4.4
*
* - Solaris 8 has `select_large_fdset`
*
* - Mac OS X 10.7 (Lion)
* `select(2)` returns `EINVAL` if `nfds` is greater than `FD_SET_SIZE` and
* `_DARWIN_UNLIMITED_SELECT` (or `_DARWIN_C_SOURCE`) isn't defined.
* http://developer.apple.com/library/mac/#releasenotes/Darwin/SymbolVariantsRelNotes/_index.html
*
* When `fd_set` is not big enough to hold big file descriptors, it should be
* allocated dynamically. Note that this assumes `fd_set` is structured as
* bitmap.
*
* `rb_fd_init` allocates the memory.
* `rb_fd_term` frees the memory.
* `rb_fd_set` may re-allocate bitmap.
*
* So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
/**@cond INTERNAL_MACRO */
#define rb_fd_ptr rb_fd_ptr
#define rb_fd_max rb_fd_max
/** @endcond */
struct timeval;
/**
* The data structure which wraps the fd_set bitmap used by select(2). This
* allows Ruby to use FD sets larger than that allowed by historic limitations
* on modern platforms.
*/
typedef struct {
int maxfd; /**< Maximum allowed number of FDs. */
fd_set *fdset; /**< File descriptors buffer */
} rb_fdset_t;
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
* (Re-)initialises a fdset. One must be initialised before other `rb_fd_*`
* operations. Analogous to calling `malloc(3)` to allocate an `fd_set`.
*
* @param[out] f An fdset to squash.
* @post `f` holds no file descriptors.
*/
void rb_fd_init(rb_fdset_t *f);
RBIMPL_ATTR_NONNULL(())
/**
* Destroys the ::rb_fdset_t, releasing any memory and resources it used. It
* must be reinitialised using rb_fd_init() before future use. Analogous to
* calling `free(3)` to release memory for an `fd_set`.
*
* @param[out] f An fdset to squash.
* @post `f` holds no file descriptors.
*/
void rb_fd_term(rb_fdset_t *f);
RBIMPL_ATTR_NONNULL(())
/**
* Wipes out the current set of FDs.
*
* @param[out] f The fdset to clear.
* @post `f` has no FDs.
*/
void rb_fd_zero(rb_fdset_t *f);
RBIMPL_ATTR_NONNULL(())
/**
* Sets an fd to a fdset.
*
* @param[in] fd A file descriptor.
* @param[out] f Target fdset.
* @post `f` holds `fd`.
*/
void rb_fd_set(int fd, rb_fdset_t *f);
RBIMPL_ATTR_NONNULL(())
/**
* Releases a specific FD from the given fdset.
*
* @param[in] fd Target FD.
* @param[out] f The fdset that holds `fd`.
* @post `f` doesn't hold n.
*/
void rb_fd_clr(int fd, rb_fdset_t *f);
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
* Queries if the given FD is in the given set.
*
* @param[in] fd Target FD.
* @param[in] f The fdset to scan.
* @retval 1 Yes there is.
* @retval 0 No there isn't.
* @see http://www.freebsd.org/cgi/query-pr.cgi?pr=91421
*/
int rb_fd_isset(int fd, const rb_fdset_t *f);
/**
* Destructively overwrites an fdset with another.
*
* @param[out] dst Target fdset.
* @param[in] src Source fdset.
* @param[in] max Maximum number of file descriptors to copy.
* @post `dst` is a copy of `src`.
*/
void rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int max);
/**
* Identical to rb_fd_copy(), except it copies unlimited number of file
* descriptors.
*
* @param[out] dst Target fdset.
* @param[in] src Source fdset.
* @post `dst` is a copy of `src`.
*/
void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);
/**
* Waits for multiple file descriptors at once.
*
* @param[in] nfds Max FD in everything passed, plus one.
* @param[in,out] rfds Set of FDs to wait for reads.
* @param[in,out] wfds Set of FDs to wait for writes.
* @param[in,out] efds Set of FDs to wait for OOBs.
* @param[in,out] timeout Max blocking duration.
* @retval -1 Failed, errno set.
* @retval 0 Timeout exceeded.
* @retval otherwise Total number of file descriptors returned.
* @post `rfds` contains readable FDs.
* @post `wfds` contains writable FDs.
* @post `efds` contains exceptional FDs.
* @post `timeout` is the time left.
* @note All pointers are allowed to be null pointers.
*/
int rb_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
* Raw pointer to `fd_set`.
*
* @param[in] f Target fdset.
* @retval NULL `f` is already terminated by rb_fd_term().
* @retval otherwise Underlying fd_set.
*
* @internal
*
* Extension library must not touch raw pointers. It was a bad idea to let
* them use it.
*/
static inline fd_set *
rb_fd_ptr(const rb_fdset_t *f)
{
return f->fdset;
}
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
* It seems this function has no use. Maybe just remove?
*
* @param[in] f A set.
* @return Number of file descriptors stored.
*/
static inline int
rb_fd_max(const rb_fdset_t *f)
{
return f->maxfd;
}
#endif /* RBIMPL_INTERN_SELECT_LARGESIZE_H */
include/ruby/internal/intern/eval.h 0000644 00000020770 15040330603 0013363 0 ustar 00 #ifndef RBIMPL_INTERN_EVAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_EVAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Pre-1.9 era evaluator APIs (now considered miscellaneous).
*/
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* eval.c */
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_raise(), except it raises the passed exception instance as-
* is instead of creating new one.
*
* @param[in] exc An instance of a subclass of ::rb_eException.
* @exception exc What is passed.
* @exception rb_eTypeError `exc` is not an exception.
* @note It never returns.
*
* @internal
*
* Wellll actually, it can take more than what is described above. This
* function tries to call `exception` method of the passed object. If that
* function returns an exception object that is used instead.
*/
void rb_exc_raise(VALUE exc);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_fatal(), except it raises the passed exception instance as-
* is instead of creating new one.
*
* @param[in] exc An instance of a subclass of ::rb_eException.
* @exception exc What is passed.
* @note It never returns.
*
* @internal
*
* You know what...? Using this API you can make arbitrary exceptions, like
* `RuntimeError`, that doesn't interface with `rescue` clause. This is very
* confusing.
*/
void rb_exc_fatal(VALUE exc);
/* process.c */
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_exit(), except how arguments are passed.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Contains at most one of the following:
* - ::RUBY_Qtrue - means `EXIT_SUCCESS`.
* - ::RUBY_Qfalse - means `EXIT_FAILURE`.
* - Numerical value - takes that value.
* @exception rb_eArgError Wrong `argc`.
* @exception rb_eSystemExit Exception representing the exit status.
* @note It never returns.
*/
VALUE rb_f_exit(int argc, const VALUE *argv);
RBIMPL_ATTR_NORETURN()
/**
* This is similar to rb_f_exit(). In fact on some situation it internally
* calls rb_exit(). But can be very esoteric on occasions.
*
* It takes up to one argument. If an argument is passed, it tries to display
* that. Otherwise if there is `$!`, displays that exception instead. It
* finally raise ::rb_eSystemExit in both cases.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Contains at most one string-ish object.
* @exception rb_eArgError Wrong `argc`.
* @exception rb_eTypeError No conversion from `argv[0]` to String.
* @exception rb_eSystemExit Exception representing `EXIT_FAILURE`.
* @note It never returns.
*/
VALUE rb_f_abort(int argc, const VALUE *argv);
/* eval.c*/
RBIMPL_ATTR_NORETURN()
/**
* Raises an instance of ::rb_eInterrupt.
*
* @exception rb_eInterrupt Always raises this exception.
* @note It never returns.
*/
void rb_interrupt(void);
/**
* Queries the name of the Ruby level method that is calling this function.
* The "name" in this context is the one assigned to the function for the first
* time (note that methods can have multiple names via aliases).
*
* @retval 0 There is no method (e.g. toplevel context).
* @retval otherwise The name of the current method.
*/
ID rb_frame_this_func(void);
RBIMPL_ATTR_NORETURN()
/**
* This function is to re-throw global escapes. Such global escapes include
* exceptions, `throw`, `break`, for example.
*
* It makes sense only when used in conjunction with "protect" series APIs
* e.g. rb_protect(), rb_load_protect(), rb_eval_string_protect(), etc. In
* case these functions experience global escapes, they fill their opaque
* `state` return buffer. You can ignore such escapes. But if you decide
* otherwise, you have to somehow escape globally again. This function is used
* for that purpose.
*
* @param[in] state Opaque state of execution.
* @note It never returns.
*
* @internal
*
* Though not a part of our public API, `state` is in fact an enum
* ruby_tag_type. You can see the potential values by looking at vm_core.h.
*/
void rb_jump_tag(int state);
/**
* Calls `initialize` method of the passed object with the passed arguments.
* It also forwards the implicitly passed block to the method.
*
* @param[in] obj Receiver object.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed as-is to `obj.initialize`.
* @exception rb_eException Any exceptions happen inside.
*/
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv);
/**
* Identical to rb_obj_call_init(), except you can specify how to handle the
* last element of the given array.
*
* @param[in] obj Receiver object.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed as-is to `obj.initialize`.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
*/
void rb_obj_call_init_kw(VALUE, int, const VALUE*, int);
/**
* Identical to rb_frame_this_func(), except it returns the named used to call
* the method.
*
* @retval 0 There is no method (e.g. toplevel context).
* @retval otherwise The name of the current method.
*/
ID rb_frame_callee(void);
/**
* Constructs an exception object from the list of arguments, in a manner
* similar to Ruby's `raise`. This function can take:
*
* - No arguments at all, i.e. `argc == 0`. This is not a failure. It
* returns ::RUBY_Qnil then.
*
* - An object, which is an instance of ::rb_cString. In this case an
* instance of ::rb_eRuntimeError whose message is the passed string is
* created then returned.
*
* - An object, which responds to `exception` method, and optionally its
* argument, and optionally its backtrace. For example instances of
* subclasses of ::rb_eException have this method. What is returned from
* the method is returned.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv 0 up to 3 objects.
* @exception rb_eArgError Wrong `argc`.
* @exception rb_eTypeError `argv[0].exception` returned non-exception.
* @return An instance of a subclass of ::rb_eException.
*
* @internal
*
* Historically this was _the_ way `raise` converted its arguments to an
* exception. However they diverged.
*/
VALUE rb_make_exception(int argc, const VALUE *argv);
/* eval_jump.c */
/**
* Registers a function that shall run on process exit. Registered functions
* run in reverse-chronological order, mixed with syntactic `END` block and
* `Kernel#at_exit`.
*
* @param[in] func Function to run at process exit.
* @param[in] arg Passed as-is to `func`.
*/
void rb_set_end_proc(void (*func)(VALUE arg), VALUE arg);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_EVAL_H */
include/ruby/internal/intern/string.h 0000644 00000206571 15040330603 0013747 0 ustar 00 #ifndef RBIMPL_INTERN_STRING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_STRING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cString.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/variable.h" /* rb_gvar_setter_t */
#include "ruby/st.h" /* st_index_t */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* string.c */
/**
* Allocates an instance of ::rb_cString.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "binary" encoding, whose contents are verbatim copy of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
*/
VALUE rb_str_new(const char *ptr, long len);
/**
* Identical to rb_str_new(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_str_new_cstr(const char *ptr);
/**
* Identical to rb_str_new_cstr(), except it takes a Ruby's string instead of
* C's. Implementation wise it creates a string that shares the backend memory
* region with the receiver. So the name. But there is no way for extension
* libraries to know if a string is of such variant.
*
* @param[in] str An object of ::RString.
* @return An allocated instance of ::rb_cString, which shares the
* encoding, length, and contents with the passed string.
* @pre `str` must not be any arbitrary object except ::RString.
* @note Use #StringValue to enforce the precondition.
*/
VALUE rb_str_new_shared(VALUE str);
/**
* Creates a frozen copy of the string, if necessary. This function does
* nothing when the passed string is already frozen. Otherwise, it allocates a
* copy of it, which is frozen. The passed string is untouched either ways.
*
* @param[in] str An object of ::RString.
* @return Something frozen.
* @pre `str` must not be any arbitrary object except ::RString.
* @note Use #StringValue to enforce the precondition.
*/
VALUE rb_str_new_frozen(VALUE str);
/**
* Identical to rb_str_new(), except it takes the class of the allocating
* object.
*
* @param[in] obj A string-ish object.
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of the class of `obj`, of `len` bytes length, of
* "binary" encoding, whose contents are verbatim copy of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
*
* @internal
*
* Why it doesn't take an instance of ::rb_cClass?
*/
VALUE rb_str_new_with_class(VALUE obj, const char *ptr, long len);
/**
* Identical to rb_str_new(), except it generates a string of "default
* external" encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "default external" is fully defined over
* the given contents, then the return value is a string of
* "default external" encoding, whose contents are the converted
* ones. Otherwise the string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
*/
VALUE rb_external_str_new(const char *ptr, long len);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_external_str_new(), except it assumes the passed pointer is
* a pointer to a C string. It can also be seen as a routine identical to
* rb_str_new_cstr(), except it generates a string of "default external"
* encoding.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "default external" is fully defined over
* the given contents, then the return value is a string of
* "default external" encoding, whose contents are the converted
* ones. Otherwise the string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_external_str_new_cstr(const char *ptr);
/**
* Identical to rb_str_new(), except it generates a string of "locale"
* encoding. It can also be seen as a routine identical to
* rb_external_str_new(), except it generates a string of "locale" encoding
* instead of "default external" encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "locale" is fully defined over the given
* contents, then the return value is a string of "locale"
* encoding, whose contents are the converted ones. Otherwise the
* string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
*/
VALUE rb_locale_str_new(const char *ptr, long len);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_locale_str_new(), except it assumes the passed pointer is a
* pointer to a C string. It can also be seen as a routine identical to
* rb_external_str_new_cstr(), except it generates a string of "locale"
* encoding instead of "default external".
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "locale" is fully defined over the given
* contents, then the return value is a string of "locale"
* encoding, whose contents are the converted ones. Otherwise the
* string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_locale_str_new_cstr(const char *ptr);
/**
* Identical to rb_str_new(), except it generates a string of "filesystem"
* encoding. It can also be seen as a routine identical to
* rb_external_str_new(), except it generates a string of "filesystem" encoding
* instead of "default external" encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "filesystem" is fully defined over the
* given contents, then the return value is a string of
* "filesystem" encoding, whose contents are the converted ones.
* Otherwise the string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
*/
VALUE rb_filesystem_str_new(const char *ptr, long len);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_filesystem_str_new(), except it assumes the passed pointer
* is a pointer to a C string. It can also be seen as a routine identical to
* rb_external_str_new_cstr(), except it generates a string of "filesystem"
* encoding instead of "default external".
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "filesystem" is fully defined over the
* given contents, then the return value is a string of
* "filesystem" encoding, whose contents are the converted ones.
* Otherwise the string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_filesystem_str_new_cstr(const char *ptr);
/**
* Allocates a "string buffer". A string buffer here is an instance of
* ::rb_cString, whose capacity is bigger than the length of it. If you can
* say that a string grows to a specific amount of bytes, this could be
* effective than resizing a string over and over again and again.
*
* @param[in] capa Designed capacity of the generating string.
* @return An empty string, of "binary" encoding, whose capacity is `capa`.
*/
VALUE rb_str_buf_new(long capa);
RBIMPL_ATTR_NONNULL(())
/**
* This is a rb_str_buf_new() + rb_str_buf_cat() combo.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
*
* @internal
*
* This must be identical to rb_str_new_cstr(), except done in inefficient way?
* @shyouhei doesn't understand why this is not a simple alias.
*/
VALUE rb_str_buf_new_cstr(const char *ptr);
/**
* Allocates a "temporary" string. This is a hidden empty string. Handy on
* occasions.
*
* @param[in] len Designed length of the string.
* @return A hidden, empty string.
* @see rb_obj_hide()
*/
VALUE rb_str_tmp_new(long len);
/**
* Identical to rb_str_new(), except it generates a string of "US ASCII"
* encoding. This is different from rb_external_str_new(), not only for the
* output encoding, but also it doesn't convert the contents.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "US ASCII" encoding, whose contents are verbatim copy of `ptr`.
*/
VALUE rb_usascii_str_new(const char *ptr, long len);
/**
* Identical to rb_str_new_cstr(), except it generates a string of "US ASCII"
* encoding. It can also be seen as a routine Identical to
* rb_usascii_str_new(), except it assumes the passed pointer is a pointer to a
* C string.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "US ASCII" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_usascii_str_new_cstr(const char *ptr);
/**
* Identical to rb_str_new(), except it generates a string of "UTF-8" encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "UTF-8" encoding, whose contents are verbatim copy of `ptr`.
*/
VALUE rb_utf8_str_new(const char *ptr, long len);
/**
* Identical to rb_str_new_cstr(), except it generates a string of "UTF-8"
* encoding. It can also be seen as a routine Identical to
* rb_usascii_str_new(), except it assumes the passed pointer is a pointer to a
* C string.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "UTF-8" encoding, whose contents
* are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_utf8_str_new_cstr(const char *ptr);
/**
* @name Special strings that are backended by C string literals.
*
* *_str_new_static functions are intended for C string literals.
* They require memory in the range [ptr, ptr+len] to always be readable.
* Note that this range covers a total of len + 1 bytes.
*
* @{
*/
/**
* Identical to rb_str_new(), except it takes a C string literal.
*
* @param[in] ptr A C string literal.
* @param[in] len `strlen(ptr)`.
* @exception rb_eArgError `len` out of range of `size_t`.
* @pre `ptr` must be a C string constant.
* @return An instance of ::rb_cString, of "binary" encoding, whose backend
* storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*
* @internal
*
* Surprisingly it can take NULL, and generates an empty string.
*/
VALUE rb_str_new_static(const char *ptr, long len);
/**
* Identical to rb_str_new_static(), except it generates a string of "US ASCII"
* encoding instead of "binary". It can also be seen as a routine identical to
* rb_usascii_str_new(), except it takes a C string literal.
*
* @param[in] ptr A C string literal.
* @param[in] len `strlen(ptr)`.
* @exception rb_eArgError `len` out of range of `size_t`.
* @pre `ptr` must be a C string constant.
* @return An instance of ::rb_cString, of "US ASCII" encoding, whose
* backend storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
VALUE rb_usascii_str_new_static(const char *ptr, long len);
/**
* Identical to rb_str_new_static(), except it generates a string of "UTF-8"
* encoding instead of "binary". It can also be seen as a routine identical to
* rb_utf8_str_new(), except it takes a C string literal.
*
* @param[in] ptr A C string literal.
* @param[in] len `strlen(ptr)`.
* @exception rb_eArgError `len` out of range of `size_t`.
* @pre `ptr` must be a C string constant.
* @return An instance of ::rb_cString, of "UTF-8" encoding, whose backend
* storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
VALUE rb_utf8_str_new_static(const char *ptr, long len);
/** @} */
/**
* Identical to rb_interned_str(), except it takes a Ruby's string instead of
* C's. It can also be seen as a routine identical to to rb_str_new_shared(),
* except it returns an infamous "f"string.
*
* @param[in] str An object of ::RString.
* @return An instance of ::rb_cString, either cached or allocated, which
* has the identical encoding, length, and contents with the passed
* string.
* @pre `str` must not be any arbitrary object except ::RString.
* @note Use #StringValue to enforce the precondition.
*
* @internal
*
* It actually finds or creates a fstring of the needed property, and
* destructively modifies the receiver behind-the-scene so that it becomes a
* shared string whose parent is the returning fstring.
*/
VALUE rb_str_to_interned_str(VALUE str);
/**
* Identical to rb_str_new(), except it returns an infamous "f"string. What is
* a fstring? Well it is a special subkind of strings that is immutable,
* deduped globally, and managed by our GC. It is much like a Symbol (in fact
* Symbols are dynamic these days and are backended using fstrings). This
* concept has been silently introduced at some point in 2.x era. Since then
* it gained wider acceptance in the core. Starting from 3.x extension
* libraries can also generate ones.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eArgError `len` is negative.
* @return A found or created instance of ::rb_cString, of `len` bytes
* length, of "binary" encoding, whose contents are identical to
* that of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
*/
VALUE rb_interned_str(const char *ptr, long len);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_interned_str(), except it assumes the passed pointer is a
* pointer to a C's string. It can also be seen as a routine identical to to
* rb_str_to_interned_str(), except it takes a C's string instead of Ruby's.
* Or it can also be seen as a routine identical to rb_str_new_cstr(), except
* it returns an infamous "f"string.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
*/
VALUE rb_interned_str_cstr(const char *ptr);
/**
* Destroys the given string for no reason.
*
* @warning DO NOT USE IT.
* @warning Leave this task to our GC.
* @warning It was a bad idea at the first place to let you know about it.
*
* @param[out] str The string to be executed.
* @post The given string no longer exists.
* @note Maybe `String#clear` could be what you want.
*
* @internal
*
* Should have moved this to `internal/string.h`.
*/
void rb_str_free(VALUE str);
/**
* Replaces the contents of the former with the latter.
*
* @param[out] dst Destination object.
* @param[in] src Source object.
* @pre Both objects must not be any arbitrary objects except
* ::RString.
* @post `dst`'s former components are abandoned. It now has the
* identical encoding, length, and contents to `src`.
* @see rb_str_replace()
*
* @internal
*
* @shyouhei doesn't understand why this is useful to extension libraries.
* Just use rb_str_replace(). What's wrong with that?
*/
void rb_str_shared_replace(VALUE dst, VALUE src);
/**
* Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of
* C's. It can also be seen as a routine identical to rb_str_shared_replace(),
* except it appends instead of replaces.
*
* @param[out] dst Destination object.
* @param[in] src Source object.
* @exception rb_eEncCompatError Can't mix the encodings.
* @exception rb_eArgError Result string too big.
* @return The passed `dst`.
* @pre Both objects must not be any arbitrary objects except
* ::RString.
* @post `dst` has the contents of `src` appended, with encoding
* converted into `dst`'s one, into the end of `dst`.
*/
VALUE rb_str_buf_append(VALUE dst, VALUE src);
/** @alias{rb_str_cat} */
VALUE rb_str_buf_cat(VALUE, const char*, long);
/** @alias{rb_str_cat_cstr} */
VALUE rb_str_buf_cat2(VALUE, const char*);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_str_cat_cstr(), except it additionally assumes the source
* string be a NUL terminated ASCII string.
*
* @param[out] dst Destination object.
* @param[in] src Source string.
* @exception rb_eArgError Result string too big.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary object except ::RString.
* @pre `src` must be a NUL terminated ASCII string.
* @post `dst` has the contents of `src` appended, with encoding
* converted into `dst`'s one, into the end of `dst`.
*/
VALUE rb_str_buf_cat_ascii(VALUE dst, const char *src);
/**
* Try converting an object to its stringised representation using its `to_s`
* method, if any. If there is no such thing, it resorts to rb_any_to_s()
* output.
*
* @param[in] obj Arbitrary ruby object to stringise.
* @return An instance of ::rb_cString.
*/
VALUE rb_obj_as_string(VALUE obj);
/**
* Try converting an object to its stringised representation using its `to_str`
* method, if any. If there is no such thing, returns ::RUBY_Qnil.
*
* @param[in] obj Arbitrary ruby object to stringise.
* @exception rb_eTypeError `obj.to_str` returned something non-String.
* @retval RUBY_Qnil No conversion from obj to String defined.
* @return otherwise Stringised representation of `obj`.
* @see rb_io_check_io
* @see rb_check_array_type
* @see rb_check_hash_type
*/
VALUE rb_check_string_type(VALUE obj);
/**
* Asserts that the given string's encoding is (Ruby's definition of) ASCII
* compatible.
*
* @param[in] obj An instance of ::rb_cString.
* @exception rb_eEncCompatError `obj` is ASCII incompatible.
*
* @internal
*
* @shyouhei doesn't know if this is an Easter egg or an official feature, but
* this function can in fact take non-strings such as Symbols, Regexps, IOs,
* etc. However if something unsupported is passed, it causes SEGV. It seems
* the feature is kind of untested.
*/
void rb_must_asciicompat(VALUE obj);
/**
* Duplicates a string.
*
* @param[in] str String in question to duplicate.
* @return A duplicated new instance.
* @pre `str` must be of ::RString.
*/
VALUE rb_str_dup(VALUE str);
/**
* I guess there is no use case of this function in extension libraries, but
* this is a routine identical to rb_str_dup(), except it always creates an
* instance of ::rb_cString regardless of the given object's class. This makes
* the most sense when the passed string is formerly hidden by rb_obj_hide().
*
* @param[in] str A string, possibly hidden.
* @return A duplicated new instance of ::rb_cString.
*/
VALUE rb_str_resurrect(VALUE str);
/**
* Obtains a "temporary lock" of the string. This advisory locking mechanism
* prevents other cooperating threads from tampering the receiver. The same
* thing could be done via freeze mechanism, but this one can also be unlocked
* using rb_str_unlocktmp().
*
* @param[out] str String to lock.
* @exception rb_eRuntimeError `str` already locked.
* @return The given string.
* @post The string is locked.
*/
VALUE rb_str_locktmp(VALUE str);
/**
* Releases a lock formerly obtained by rb_str_locktmp().
*
* @param[out] str String to unlock.
* @exception rb_eRuntimeError `str` already unlocked.
* @return The given string.
* @post The string is locked.
*/
VALUE rb_str_unlocktmp(VALUE str);
/** @alias{rb_str_new_frozen} */
VALUE rb_str_dup_frozen(VALUE);
/** @alias{rb_str_new_frozen} */
#define rb_str_dup_frozen rb_str_new_frozen
/**
* Generates a new string, concatenating the former to the latter. It can also
* be seen as a routine identical to rb_str_append(), except it doesn't tamper
* the passed strings to create a new one instead.
*
* @param[in] lhs Source string #1.
* @param[in] rhs Source string #2.
* @exception rb_eEncCompatError Can't mix the encodings.
* @exception rb_eArgError Result string too big.
* @return A new string containing `rhs` concatenated to `lhs`.
* @pre Both objects must not be any arbitrary objects except ::RString.
* @note This operation doesn't commute. Don't get confused by the
* "plus" terminology. For historical reasons there are some
* noncommutative `+`s in Ruby. This is one of such things. There
* has been a long discussion around `+`s in programming languages.
*/
VALUE rb_str_plus(VALUE lhs, VALUE rhs);
/**
* Repetition of a string.
*
* @param[in] str String to repeat.
* @param[in] num Count, something numeric.
* @exception rb_eArgError `num` is negative.
* @return A new string repeating `num` times of `str`.
*/
VALUE rb_str_times(VALUE str, VALUE num);
/**
* Byte offset to character offset conversion. This makes sense when the
* receiver is in a multibyte encoding. The string's i-th character does not
* always sit at its i-th byte. This function scans the contents to find the
* character index that matches the byte index. Generally speaking this is an
* `O(n)` operation. Could be slow.
*
* @param[in] str The string to scan.
* @param[in] pos Offset, in bytes.
* @return Offset, in characters.
*/
long rb_str_sublen(VALUE str, long pos);
/**
* This is the implementation of two-argumented `String#slice`.
*
* - Returns the substring of the given `len` found in `str` at offset `beg`:
*
* ```ruby
* 'foo'[0, 2] # => "fo"
* 'foo'[0, 0] # => ""
* ```
*
* - Counts backward from the end of `str` if `beg` is negative:
*
* ```ruby
* 'foo'[-2, 2] # => "oo"
* ```
*
* - Special case: returns a new empty string if `beg` is equal to the length
* of `str`:
*
* ```ruby
* 'foo'[3, 2] # => ""
* ```
*
* - Returns a null pointer if `beg` is out of range:
*
* ```ruby
* 'foo'[4, 2] # => nil
* 'foo'[-4, 2] # => nil
* ```
*
* - Returns the trailing substring of `str` if `len` is large:
*
* ```ruby
* 'foo'[1, 50] # => "oo"
* ```
*
* - Returns a null pointer if `len` is negative:
*
* ```ruby
* 'foo'[0, -1] # => nil
* ```
*
* @param[in] str The string to slice.
* @param[in] beg Requested offset of the substring.
* @param[in] len Requested length of the substring.
* @retval RUBY_Qnil Parameters out of range.
* @retval otherwise A new string whose contents is the specified
* substring of `str`.
* @pre `str` must not be any arbitrary objects except ::RString.
*/
VALUE rb_str_substr(VALUE str, long beg, long len);
/**
* Identical to rb_str_substr(), except the numbers are interpreted as byte
* offsets instead of character offsets.
*
* @param[in] str The string to slice.
* @param[in] beg Requested offset of the substring.
* @param[in] len Requested length of the substring.
* @return A new string whose contents is the specified substring of `str`.
* @pre `str` must not be any arbitrary objects except ::RString.
* @pre `beg` and `len` must not point to OOB contents.
*/
VALUE rb_str_subseq(VALUE str, long beg, long len);
/**
* Identical to rb_str_substr(), except it returns a C's string instead of
* Ruby's.
*
* @param[in] str The string to slice.
* @param[in] beg Requested offset of the substring.
* @param[in,out] len Requested length of the substring.
* @retval NULL Parameters out of range.
* @retval otherwise A pointer inside of `str`'s backend storage where
* the specified substring exist.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post `len` is updated to have the length of the return value.
*/
char *rb_str_subpos(VALUE str, long beg, long *len);
/**
* Declares that the string is about to be modified. This for instance let the
* string have a dedicated backend storage.
*
* @param[out] str String about to be modified.
* @exception rb_eRuntimeError `str` is `locktmp`-ed.
* @exception rb_eFrozenError `str` is frozen.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post Upon successful return the passed string is eligible to be
* modified.
*/
void rb_str_modify(VALUE str);
/**
* Identical to rb_str_modify(), except it additionally expands the capacity of
* the receiver.
*
* @param[out] str Target string to modify.
* @param[in] capa Additional capacity to add.
* @exception rb_eArgError `capa` is negative.
* @exception rb_eRuntimeError `str` is `locktmp`-ed.
* @exception rb_eFrozenError `str` is frozen.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post Upon successful return the passed string is modified so that
* its capacity is increased for `capa` bytes.
*/
void rb_str_modify_expand(VALUE str, long capa);
/**
* This is the implementation of `String#freeze`.
*
* @param[out] str Target string to freeze.
* @return The passed string.
* @post Upon successful return the passed string is frozen.
*/
VALUE rb_str_freeze(VALUE str);
/**
* Overwrites the length of the string. Typically this is used to shrink a
* string that was formerly expanded.
*
* ```CXX
* extern int fd;
* auto str = rb_eval_string("'...'");
* rb_str_modify_expand(str, BUFSIZ);
* if (auto len = recv(fd, RSTRING_PTR(str), BUFSIZ, 0); len >= 0) {
* rb_str_set_len(str, len);
* }
* else {
* rb_sys_fail("recv(2)");
* }
* ```
*
* @param[out] str String to shrink.
* @param[in] len New length of the string.
* @exception rb_eRuntimeError `str` is `locktmp`-ed.
* @exception rb_eFrozenError `str` is frozen.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post Upon successful return `str`'s length is set to `len`.
*/
void rb_str_set_len(VALUE str, long len);
/**
* Overwrites the length of the string. In contrast to rb_str_set_len(), this
* function can also expand a string.
*
* @param[out] str String to shrink.
* @param[in] len New length of the string.
* @exception rb_eArgError `len` is negative.
* @exception rb_eRuntimeError `str` is `locktmp`-ed.
* @exception rb_eFrozenError `str` is frozen.
* @return The passed `str`.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post Upon successful return `str` is either expanded or shrunken to
* have its length be `len`.
*/
VALUE rb_str_resize(VALUE str, long len);
/**
* Destructively appends the passed contents to the string.
*
* @param[out] dst Destination object.
* @param[in] src Contents to append.
* @param[in] srclen Length of `src`.
* @exception rb_eArgError `srclen` is negative.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary objects except ::RString.
* @post `dst` has the contents of `ptr` appended.
*/
VALUE rb_str_cat(VALUE dst, const char *src, long srclen);
/**
* Identical to rb_str_cat(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[out] dst Destination object.
* @param[in] src Contents to append.
* @exception rb_eArgError Result string too big.
* @exception rb_eArgError `src` is a null pointer.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary objects except ::RString.
* @pre `src` must not be a null pointer.
* @post `dst` has the contents of `src` appended.
*/
VALUE rb_str_cat_cstr(VALUE dst, const char *src);
/** @alias{rb_str_cat_cstr} */
VALUE rb_str_cat2(VALUE, const char*);
/**
* Identical to rb_str_buf_append(), except it converts the right hand side
* before concatenating.
*
* @param[out] dst Destination object.
* @param[in] src Source object.
* @exception rb_eEncCompatError Can't mix the encodings.
* @exception rb_eArgError Result string too big.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary objects except ::RString.
* @post `dst` has the contents of `src` appended, with encoding
* converted into `dst`'s one, into the end of `dst`.
*/
VALUE rb_str_append(VALUE dst, VALUE src);
/**
* Identical to rb_str_append(), except it also accepts an integer as a
* codepoint. This resembles `String#<<`.
*
* @param[out] dst Destination object.
* @param[in] src Source object, String or Numeric.
* @exception rb_eRangeError Source numeric is out of range.
* @exception rb_eEncCompatError Source string too long.
* @exception rb_eArgError Result string too big.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary objects except ::RString.
* @post `dst` has the contents of `src` appended, with encoding
* converted into `dst`'s one, into the end of `dst`.
*/
VALUE rb_str_concat(VALUE dst, VALUE src);
/* random.c */
/**
* This is a universal hash function.
*
* @warning This function changes its value per process.
* @param[in] ptr Target message.
* @param[in] len Length of `ptr` in bytes.
* @return A pseudorandom number suitable for Hash's hash value.
* @see Aumasson, JP., Bernstein, D.J., "SipHash: A Fast Short-Input
* PRF", In proceedings of 13th International Conference on
* Cryptology in India (INDOCRYPT 2012), LNCS 7668, pp. 489-508,
* 2012. http://doi.org/10.1007/978-3-642-34931-7_28
*/
st_index_t rb_memhash(const void *ptr, long len);
/**
* Starts a series of hashing. Suppose you have a struct:
*
* ```CXX
* struct foo_tag {
* unsigned char bar;
* uint32_t baz;
* };
* ```
*
* It is not a wise idea to call rb_memhash() over it, because there could be
* padding bits. Instead you should explicitly iterate over each fields:
*
* ```CXX
* foo_tag foo = { 0, 0, };
* st_index_t hash = 0;
*
* hash = rb_hash_start(0);
* hash = rb_hash_uint(hash, foo.bar);
* hash = rb_hash_uint32(hash, foo.baz);
* hash = rb_hash_end(hash);
* ```
*
* @param[in] i Initial value.
* @return A hash value.
*/
st_index_t rb_hash_start(st_index_t i);
/** @alias{st_hash_uint32} */
#define rb_hash_uint32(h, i) st_hash_uint32((h), (i))
/** @alias{st_hash_uint} */
#define rb_hash_uint(h, i) st_hash_uint((h), (i))
/** @alias{st_hash_end} */
#define rb_hash_end(h) st_hash_end(h)
/* string.c */
/**
* Calculates a hash value of a string. This is one of the two functions that
* constructs struct ::st_hash_type.
*
* @param[in] str An object of ::RString.
* @return A hash value.
* @pre `str` must not be any arbitrary object except ::RString.
*
* @internal
*
* Although safe to call, there must be no particular use case of this function
* for extension libraries. Only ruby internals must know about it.
*
* This is not a simple alias of rb_memhash(), because it considers the passed
* string's encoding as well as its contents.
*/
st_index_t rb_str_hash(VALUE str);
/**
* Compares two strings. This is one of the two functions that constructs
* struct ::st_hash_type.
*
* @param[in] str1 A string.
* @param[in] str2 Another string.
* @retval 1 They have identical contents, length, and encodings.
* @retval 0 Otherwise.
* @pre Both objects must not be any arbitrary objects except
* ::RString.
*
* @internal
*
* In contrast to rb_str_hash(), this could be handy for comparison that only
* concerns equality. rb_str_cmp() returns 1, 0, -1.
*/
int rb_str_hash_cmp(VALUE str1, VALUE str2);
/**
* Checks if two strings are comparable each other or not. Because
* rb_str_cmp() must return "lesser than" or "greater than" information,
* comparing two strings needs a stricter restriction. Both sides must be in a
* same set of strings which have total order. This is to check that property.
* Intuitive it sounds? But they can have different encodings. A character
* and another might or might not appear in the same order in their codepoints.
* It is complicated than you think.
*
* @param[in] str1 A string.
* @param[in] str2 Another string.
* @retval 1 They agree on a total order.
* @retval 0 Otherwise.
* @pre Both objects must not be any arbitrary objects except
* ::RString.
*/
int rb_str_comparable(VALUE str1, VALUE str2);
/**
* Compares two strings, as in `strcmp(3)`. This does not consider the current
* locale, but considers the encodings of both sides instead.
*
* @param[in] lhs A string.
* @param[in] rhs Another string.
* @retval -1 `lhs` is "bigger than" `rhs`.
* @retval 1 `rhs` is "bigger than" `lhs`.
* @retval 0 Otherwise, e.g. not comparable.
* @pre Both objects must not be any arbitrary objects except
* ::RString.
*/
int rb_str_cmp(VALUE lhs, VALUE rhs);
/**
* Equality of two strings.
*
* If `str2` is not a String, it resorts to `str2 == str1`. Otherwise if they
* are not comparable, returns ::RUBY_Qfalse. Otherwise if they have the same
* contents and the length, returns ::RUBY_Qtrue. Otherwise, returns
* ::RUBY_Qfalse.
*
* @param[in] str1 A string.
* @param[in] str2 Another string.
* @retval RUBY_Qtrue They are equal.
* @retval RUBY_Qfalse They are either different, or not comparable.
*/
VALUE rb_str_equal(VALUE str1, VALUE str2);
/**
* Shrinks the given string for the given number of bytes.
*
* @param[out] str String to squash.
* @param[in] len Number of bytes to reduce.
* @exception rb_eRuntimeError `str` is `locktmp`-ed.
* @exception rb_eFrozenError `str` is frozen.
* @return The passed `str`.
* @pre `str` must not be any arbitrary objects except ::RString.
* @post `str` is shrunken.
* @warning Can break a multibyte character in middle.
*
* @internal
*
* What if `len` is negative?
*/
VALUE rb_str_drop_bytes(VALUE str, long len);
/**
* Replaces some (or all) of the contents of the given string. This is the
* implementation of three-argumented `String#[]=`.
*
* @param[out] dst Target string to update.
* @param[in] beg Offset of the affected portion.
* @param[in] len Length of the affected portion.
* @param[in] src Object to be assigned.
* @exception rb_eTypeError `src` has no implicit conversion to String.
* @exception rb_eIndexError `len` is negative, or `beg` is OOB.
* @exception rb_eRuntimeError `dst` is `locktmp`-ed.
* @exception rb_eFrozenError `dst` is frozen.
* @note Unlike rb_str_substr(), this function raises.
* @post A portion of `dst` from `beg` to `len` is the stringised
* representation of `src`. If that replacement string is not the
* same length as the portion it is replacing, `dst` will be
* resized accordingly.
*/
void rb_str_update(VALUE dst, long beg, long len, VALUE src);
/**
* Replaces the contents of the former object with the stringised contents of
* the latter.
*
* @param[out] dst Destination object.
* @param[in] src Source object.
* @exception rb_eTypeError `src` has no implicit conversion to String.
* @exception rb_eRuntimeError `dst` is `locktmp`-ed.
* @exception rb_eFrozenError `dst` is frozen.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary object except ::RString.
* @post `dst`'s former components are abandoned. It now has the
* identical encoding, length, and contents to `src`.
*/
VALUE rb_str_replace(VALUE dst, VALUE src);
/**
* Generates a "readable" version of the receiver.
*
* @warning The output is _insecure_. Never feed one to `eval`.
* @warning The output is not always in the same encoding as the given one.
* @warning A character might or might not be escaped, depending on the
* result encoding.
* @param[in] str String to inspect.
* @return Its inspection, either in default internal encoding if any, or
* in default external encoding otherwise.
* @see rb_str_dump()
*
* @internal
*
* This is a (silent) fix of an actual vulnerability feeding `inspect` output
* strings to `eval`:
* https://github.com/hiki/hiki/commit/8771a6e25198e264a2bf9dc1c102fea2cc8ff975
*
* ... and its advisory:
* http://hikiwiki.org/en/advisory20040712.html
*/
VALUE rb_str_inspect(VALUE str);
/**
* "Inverse" of rb_eval_string(). Returns a quoted version of the string. All
* non-printing characters are replaced by `\uNNNN` or `\xHH` notation and all
* special characters are escaped. The result string is guaranteed to render a
* string of the same contents when passed to `eval` and friends.
*
* @param[in] str String to dump.
* @exception rb_eRuntimeError Too many escape sequences causes integer
* overflow on the length of the string.
* @return An US-ASCII string that includes all the necessary info to
* reconstruct the original string.
*/
VALUE rb_str_dump(VALUE str);
/**
* Divides the given string based on the given delimiter. This is the
* 1-argument 0-block version of `String#split`.
*
* @param[in] str Object in question to split.
* @param[in] delim Delimiter, in C string.
* @exception rb_eTypeError `str` has no implicit conversion to String.
* @exception rb_eArgError `delim` is a null pointer.
* @return An array of strings, which are substrings of the passed `str`.
* If `delim` is an empty C string (i.e. `""`), `str` is split into
* each characters. If `delim` is a C string whose sole content is
* a whitespace (i.e. `" "`), `str` is split on whitespaces, with
* leading and trailing whitespace and runs of contiguous
* whitespace characters ignored. Otherwise, `str` is split
* according to `delim`.
*/
VALUE rb_str_split(VALUE str, const char *delim);
/**
* This is a ::rb_gvar_setter_t that refutes non-string assignments.
*
* @exception rb_eTypeError Passed something non-string.
*/
rb_gvar_setter_t rb_str_setter;
/* symbol.c */
/**
* Identical to rb_to_symbol(), except it assumes the receiver being an
* instance of ::RString.
*
* @param[in] str The name of the id.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given `str`.
* @pre `str` must not be any arbitrary object except ::RString.
* @note These days Ruby internally has two kinds of symbols
* (static/dynamic). Symbols created using this function would
* become dynamic ones; i.e. would be garbage collected. It could
* be safer for you to use it than alternatives, when applicable.
*/
VALUE rb_str_intern(VALUE str);
/* string.c */
/**
* This is an rb_sym2str() + rb_str_dup() combo.
*
* @param[in] sym A symbol to query.
* @return A string duplicating the symbol's backend storage.
*
* @internal
*
* This function causes SEGV when the passed value is a static symbol that
* doesn't exist.
*/
VALUE rb_sym_to_s(VALUE sym);
/**
* Counts the number of characters (not bytes) that are stored inside of the
* given string. This of course depends on its encoding. Also this function
* generally runs in O(n), because for instance you have to scan the entire
* string to know how many characters are there in a UTF-8 string.
*
* @param[in] str Target string to query.
* @return Its number of characters.
*/
long rb_str_strlen(VALUE str);
/**
* Identical to rb_str_strlen(), except it returns the value in ::rb_cInteger.
*
* @param[in] str Target string to query.
* @return Its number of characters.
*/
VALUE rb_str_length(VALUE);
/**
* "Inverse" of rb_str_sublen(). This function scans the contents to find the
* byte index that matches the character index. Generally speaking this is an
* `O(n)` operation. Could be slow.
*
* @param[in] str The string to scan.
* @param[in] pos Offset, in characters.
* @return Offset, in bytes.
*/
long rb_str_offset(VALUE str, long pos);
RBIMPL_ATTR_PURE()
/**
* Queries the capacity of the given string.
*
* @see ::RString::capa
* @param[in] str String in question.
* @return Its capacity.
*/
size_t rb_str_capacity(VALUE str);
/**
* Shortens `str` and adds three dots, an ellipsis, if it is longer than `len`
* characters. The length of the returned string in characters is less than or
* equal to `len`. If the length of `str` is less than or equal `len`, returns
* `str` itself. The encoding of returned string is equal to that of passed
* one. The class of returned string is equal to that of passed one.
*
* @param[in] str The string to shorten.
* @param[in] len The maximum string length.
* @exception rb_eIndexError `len` is negative.
* @retval str No need to add ellipsis.
* @retval otherwise A new, shortened string.
* @note The length is counted in characters.
*/
VALUE rb_str_ellipsize(VALUE str, long len);
/**
* "Cleanses" the string. A string has its encoding and its contents. They,
* in practice, do not always fit. There are strings in the wild that are
* "broken"; include bit patterns that are not allowed by its encoding. That
* can happen when a user copy&pasted something bad, network input got
* clobbered by a middleman, cosmic rays hit the physical memory, and many more
* occasions. This function takes such strings, and fills the "broken" portion
* with the passed replacement bit pattern.
*
* This function also takes a ruby block. That is a neat way to do things, but
* can be annoying when the caller function want to use a block for another
* purpose.
*
* @param[in] str Target string to scrub.
* @param[in] repl Replacement string. When it is a string,
* this function takes that as a replacement.
* When it is ::RUBY_Qnil, this function tries
* to yield a block (if any) and takes its
* evaluated value as a replacement. In case
* of ::RUBY_Qnil without a block, this
* function takes an encoding-specific default
* character (`U+FFFD`, for instance) as a last
* resort.
* @exception rb_eTypeError `repl` is neither string nor nil.
* @exception rb_eArgError `repl` itself is broken.
* @exception rb_eEncCompatError `repl` and `str` are incompatible.
* @retval RUBY_Qnil `str` is already clean.
* @retval otherwise A new, clean string.
*/
VALUE rb_str_scrub(VALUE str, VALUE repl);
/**
* Searches for the "successor" of a string. This function is complicated!
* This is the only function in the entire ruby API (either C or Ruby) that
* generates a string out of thin air. First, the successor to an empty string
* is a new empty string:
*
* ```ruby
* ''.succ # => ""
* ```
*
* Otherwise the successor is calculated by "incrementing" characters. The
* first character to be incremented is the rightmost alphanumeric: or, if no
* alphanumerics, the rightmost character:
*
* ```ruby
* 'THX1138'.succ # => "THX1139"
* '<<koala>>'.succ # => "<<koalb>>"
* '***'.succ # => '**+'
* ```
*
* The successor to a digit is another digit, "carrying" to the next-left
* character for a "rollover" from 9 to 0, and prepending another digit if
* necessary:
*
* ```ruby
* '00'.succ # => "01"
* '09'.succ # => "10"
* '99'.succ # => "100"
* '-9'.succ # => "-10"
* ```
*
* The successor to a letter is another letter of the same case, carrying to
* the next-left character for a rollover, and prepending another same-case
* letter if necessary:
*
* ```ruby
* 'aa'.succ # => "ab"
* 'az'.succ # => "ba"
* 'zz'.succ # => "aaa"
* 'AA'.succ # => "AB"
* 'AZ'.succ # => "BA"
* 'ZZ'.succ # => "AAA"
* ```
*
* The successor to a non-alphanumeric character is the next character in the
* underlying character set's collating sequence, carrying to the next-left
* character for a rollover, and prepending another character if necessary:
*
* ```ruby
* s = "\u03A1"
* s.succ # => "\u03A3" # There is no such thing like \u03A2.
* s = 255.chr * 3
* s # => "\xFF\xFF\xFF"
* s.succ # => "\x01\x00\x00\x00"
* ```
*
* Carrying can occur between and among mixtures of alphanumeric characters:
*
* ```ruby
* s = 'zz99zz99'
* s.succ # => "aaa00aa00"
* s = '99zz99zz'
* s.succ # => "100aa00aa"
* s = '1.9.9'
* s.succ # => "2.0.0"
* ```
*
* @param[in] orig Predecessor string.
* @return Successor string.
*/
VALUE rb_str_succ(VALUE orig);
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string.
* @return `strlen`, casted to `long`.
*/
static inline long
rbimpl_strlen(const char *str)
{
return RBIMPL_CAST((long)strlen(str));
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_str_new_static(str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_usascii_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_usascii_str_new_static(str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_utf8_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_utf8_str_new_static(str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_external_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_external_str_new(str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_locale_str_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
return rb_locale_str_new(str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] str A C string literal.
* @return Corresponding Ruby string.
*/
static inline VALUE
rbimpl_str_buf_new_cstr(const char *str)
{
long len = rbimpl_strlen(str);
VALUE buf = rb_str_buf_new(len);
return rb_str_buf_cat(buf, str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[out] buf A string buffer.
* @param[in] str A C string literal.
* @return `buf` itself.
*/
static inline VALUE
rbimpl_str_cat_cstr(VALUE buf, const char *str)
{
long len = rbimpl_strlen(str);
return rb_str_cat(buf, str, len);
}
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail. Don't bother.
*
* @param[in] exc An exception class.
* @param[in] str A C string literal.
* @return An instance of `exc`.
*/
static inline VALUE
rbimpl_exc_new_cstr(VALUE exc, const char *str)
{
long len = rbimpl_strlen(str);
return rb_exc_new(exc, str, len);
}
/**
* Allocates an instance of ::rb_cString.
*
* @param[in] str A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "binary" encoding, whose contents are verbatim copy of `str`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `str`.
*/
#define rb_str_new(str, len) \
((RBIMPL_CONSTANT_P(str) && \
RBIMPL_CONSTANT_P(len) ? \
rb_str_new_static : \
rb_str_new) ((str), (len)))
/**
* Identical to #rb_str_new, except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `str`.
* @pre `str` must not be a null pointer.
*/
#define rb_str_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_str_new_cstr : \
rb_str_new_cstr) (str))
/**
* Identical to #rb_str_new, except it generates a string of "US ASCII"
* encoding. This is different from rb_external_str_new(), not only for the
* output encoding, but also it doesn't convert the contents.
*
* @param[in] str A memory region of `len` bytes length.
* @param[in] len Length of `str`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "US ASCII" encoding, whose contents are verbatim copy of `str`.
*/
#define rb_usascii_str_new(str, len) \
((RBIMPL_CONSTANT_P(str) && \
RBIMPL_CONSTANT_P(len) ? \
rb_usascii_str_new_static : \
rb_usascii_str_new) ((str), (len)))
/**
* Identical to #rb_str_new, except it generates a string of "UTF-8" encoding.
*
* @param[in] str A memory region of `len` bytes length.
* @param[in] len Length of `str`, in bytes, not including the
* terminating NUL character.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of
* "UTF-8" encoding, whose contents are verbatim copy of `str`.
*/
#define rb_utf8_str_new(str, len) \
((RBIMPL_CONSTANT_P(str) && \
RBIMPL_CONSTANT_P(len) ? \
rb_utf8_str_new_static : \
rb_utf8_str_new) ((str), (len)))
/**
* Identical to #rb_str_new_cstr, except it generates a string of "US ASCII"
* encoding. It can also be seen as a routine Identical to
* #rb_usascii_str_new, except it assumes the passed pointer is a pointer to a
* C string.
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "US ASCII" encoding, whose
* contents are verbatim copy of `str`.
* @pre `str` must not be a null pointer.
*/
#define rb_usascii_str_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_usascii_str_new_cstr : \
rb_usascii_str_new_cstr) (str))
/**
* Identical to #rb_str_new_cstr, except it generates a string of "UTF-8"
* encoding. It can also be seen as a routine Identical to #rb_utf8_str_new,
* except it assumes the passed pointer is a pointer to a C string.
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "UTF-8" encoding, whose contents
* are verbatim copy of `str`.
* @pre `str` must not be a null pointer.
*/
#define rb_utf8_str_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_utf8_str_new_cstr : \
rb_utf8_str_new_cstr) (str))
/**
* Identical to #rb_str_new_cstr, except it generates a string of "default
* external" encoding.
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "default external" is fully defined over
* the given contents, then the return value is a string of
* "default external" encoding, whose contents are the converted
* ones. Otherwise the string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
* @pre `str` must not be a null pointer.
*/
#define rb_external_str_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_external_str_new_cstr : \
rb_external_str_new_cstr) (str))
/**
* Identical to #rb_external_str_new_cstr, except it generates a string of
* "locale" encoding instead of "default external".
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to "locale" is fully defined over the given
* contents, then the return value is a string of "locale"
* encoding, whose contents are the converted ones. Otherwise the
* string is a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
* @pre `str` must not be a null pointer.
*/
#define rb_locale_str_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_locale_str_new_cstr : \
rb_locale_str_new_cstr) (str))
/**
* Identical to #rb_str_new_cstr, except done differently.
*
* @param[in] str A C string.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `str`.
* @pre `str` must not be a null pointer.
*/
#define rb_str_buf_new_cstr(str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_str_buf_new_cstr : \
rb_str_buf_new_cstr) (str))
/**
* Identical to rb_str_cat(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[out] buf Destination object.
* @param[in] str Contents to append.
* @exception rb_eArgError Result string too big.
* @return The passed `buf`.
* @pre `buf` must not be any arbitrary objects except ::RString.
* @pre `str` must not be a null pointer.
* @post `buf` has the contents of `str` appended.
*/
#define rb_str_cat_cstr(buf, str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_str_cat_cstr : \
rb_str_cat_cstr) ((buf), (str)))
/**
* Identical to rb_exc_new(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[out] exc A subclass of ::rb_eException.
* @param[in] str Message to raise.
* @return An instance of `exc` whose message is `str`.
* @pre `str` must not be a null pointer.
*/
#define rb_exc_new_cstr(exc, str) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_exc_new_cstr : \
rb_exc_new_cstr) ((exc), (str)))
#define rb_str_new2 rb_str_new_cstr /**< @old{rb_str_new_cstr} */
#define rb_str_new3 rb_str_new_shared /**< @old{rb_str_new_shared} */
#define rb_str_new4 rb_str_new_frozen /**< @old{rb_str_new_frozen} */
#define rb_str_new5 rb_str_new_with_class /**< @old{rb_str_new_with_class} */
#define rb_str_buf_new2 rb_str_buf_new_cstr /**< @old{rb_str_buf_new_cstr} */
#define rb_usascii_str_new2 rb_usascii_str_new_cstr /**< @old{rb_usascii_str_new_cstr} */
#define rb_str_buf_cat rb_str_cat /**< @alias{rb_str_cat} */
#define rb_str_buf_cat2 rb_str_cat_cstr /**< @old{rb_usascii_str_new_cstr} */
#define rb_str_cat2 rb_str_cat_cstr /**< @old{rb_str_cat_cstr} */
/**
* Length of a string literal.
*
* @param[in] str A C String literal.
* @return An integer constant expression that represents `str`'s length,
* in bytes, not including the terminating NUL character.
*/
#define rb_strlen_lit(str) (sizeof(str "") - 1)
/**
* Identical to rb_str_new_static(), except it cannot take string variables.
*
* @param[in] str A C string literal.
* @pre `str` must not be a variable.
* @return An instance of ::rb_cString, of "binary" encoding, whose backend
* storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
#define rb_str_new_lit(str) rb_str_new_static((str), rb_strlen_lit(str))
/**
* Identical to rb_usascii_str_new_static(), except it cannot take string
* variables.
*
* @param[in] str A C string literal.
* @pre `str` must not be a variable.
* @return An instance of ::rb_cString, of "US ASCII" encoding, whose
* backend storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
#define rb_usascii_str_new_lit(str) rb_usascii_str_new_static((str), rb_strlen_lit(str))
/**
* Identical to rb_utf8_str_new_static(), except it cannot take string
* variables.
*
* @param[in] str A C string literal.
* @pre `str` must not be a variable.
* @return An instance of ::rb_cString, of "UTF-8" encoding, whose backend
* storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
#define rb_utf8_str_new_lit(str) rb_utf8_str_new_static((str), rb_strlen_lit(str))
/**
* Identical to rb_enc_str_new_static(), except it cannot take string
* variables.
*
* @param[in] str A C string literal.
* @param[in] enc A pointer to an encoding.
* @pre `str` must not be a variable.
* @return An instance of ::rb_cString, of the passed encoding, whose
* backend storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
*/
#define rb_enc_str_new_lit(str, enc) rb_enc_str_new_static((str), rb_strlen_lit(str), (enc))
#define rb_str_new_literal(str) rb_str_new_lit(str) /**< @alias{rb_str_new_lit} */
#define rb_usascii_str_new_literal(str) rb_usascii_str_new_lit(str) /**< @alias{rb_usascii_str_new_lit} */
#define rb_utf8_str_new_literal(str) rb_utf8_str_new_lit(str) /**< @alias{rb_utf8_str_new_lit} */
#define rb_enc_str_new_literal(str, enc) rb_enc_str_new_lit(str, enc) /**< @alias{rb_enc_str_new_lit} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_STRING_H */
include/ruby/internal/intern/hash.h 0000644 00000027170 15040330603 0013360 0 ustar 00 #ifndef RBIMPL_INTERN_HASH_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_HASH_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cHash.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/st.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* hash.c */
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_st_foreach(), except it raises exceptions when the callback
* function tampers the table during iterating over it.
*
* @param[in] st Table to iterate over.
* @param[in] func Callback function to apply.
* @param[in] arg Passed as-is to `func`.
* @exception rb_eRuntimeError `st` was tampered during iterating.
*
* @internal
*
* This is declared here because exceptions are Ruby level concept.
*
* This is in fact a very thin wrapper of rb_st_foreach_check().
*/
void rb_st_foreach_safe(struct st_table *st, st_foreach_callback_func *func, st_data_t arg);
/** @alias{rb_st_foreach_safe} */
#define st_foreach_safe rb_st_foreach_safe
/**
* Try converting an object to its hash representation using its `to_hash`
* method, if any. If there is no such thing, returns ::RUBY_Qnil.
*
* @param[in] obj Arbitrary ruby object to convert.
* @exception rb_eTypeError `obj.to_hash` returned something non-Hash.
* @retval RUBY_Qnil No conversion from `obj` to hash defined.
* @retval otherwise Converted hash representation of `obj`.
* @see rb_io_check_io
* @see rb_check_array_type
* @see rb_check_string_type
*
* @internal
*
* There is no rb_hash_to_hash() that analogous to rb_str_to_str().
* Intentional or ...?
*/
VALUE rb_check_hash_type(VALUE obj);
RBIMPL_ATTR_NONNULL(())
/**
* Iterates over a hash. This basically does the same thing as
* rb_st_foreach(). But because the passed hash is a Ruby object, its keys and
* values are both Ruby objects.
*
* @param[in] hash An instance of ::rb_cHash to iterate over.
* @param[in] func Callback function to yield.
* @param[in] arg Passed as-is to `func`.
* @exception rb_eRuntimeError `hash` was tampered during iterating.
*/
void rb_hash_foreach(VALUE hash, int (*func)(VALUE key, VALUE val, VALUE arg), VALUE arg);
/**
* Calculates a message authentication code of the passed object. The return
* value is a very small integer used as an index of a key of a table. In
* order to calculate the value this function calls `#hash` method of the
* passed object. Ruby provides you a default implementation. But if you
* implement your class in C, that default implementation cannot know the
* underlying data structure. You must implement your own `#hash` method then,
* which must return an integer of uniform distribution in a sufficiently
* instant manner.
*
* @param[in] obj Arbitrary Ruby object.
* @exception rb_eTypeError `obj.hash` returned something non-Integer.
* @return A small integer.
* @note `#hash` can return very big integers, but they get truncated.
*/
VALUE rb_hash(VALUE obj);
/**
* Creates a new, empty hash object.
*
* @return An allocated new instance of ::rb_cHash.
*/
VALUE rb_hash_new(void);
/**
* Identical to rb_hash_new(), except it additionally specifies how many keys
* it is expected to contain. This way you can create a hash that is large enough
* for your need. For large hashes it means it won't need to be reallocated and
* rehashed as much, improving performance.
*
* @param[in] capa Designed capacity of the hash.
* @return An empty Hash, whose capacity is `capa`.
*/
VALUE rb_hash_new_capa(long capa);
/**
* Duplicates a hash.
*
* @param[in] hash An instance of ::rb_cHash.
* @return An allocated new instance of ::rb_cHash, whose contents are
* a verbatim copy of from `hash`.
*/
VALUE rb_hash_dup(VALUE hash);
/** @alias{rb_obj_freeze} */
VALUE rb_hash_freeze(VALUE obj);
/**
* Queries the given key in the given hash table. If there is the key in the
* hash, returns the value associated with the key. Otherwise it returns the
* "default" value (defined per hash table).
*
* @param[in] hash Hash table to look into.
* @param[in] key Hash key to look for.
* @return Either the value associated with the key, or the default one if
* absent.
*/
VALUE rb_hash_aref(VALUE hash, VALUE key);
/**
* Identical to rb_hash_aref(), except it always returns ::RUBY_Qnil for
* misshits.
*
* @param[in] hash Hash table to look into.
* @param[in] key Hash key to look for.
* @return Either the value associated with the key, or ::RUBY_Qnil if
* absent.
* @note A hash can store ::RUBY_Qnil as an ordinary value. You cannot
* distinguish whether the key is missing, or just its associated
* value happens to be ::RUBY_Qnil, as far as you use this API.
*/
VALUE rb_hash_lookup(VALUE hash, VALUE key);
/**
* Identical to rb_hash_lookup(), except you can specify what to return on
* misshits. This is much like 2-arguments version of `Hash#fetch`.
*
* ```CXX
* VALUE hash;
* VALUE key;
* VALUE tmp = rb_obj_alloc(rb_cObject);
* VALUE val = rb_hash_lookup2(hash, key, tmp);
* if (val == tmp) {
* printf("misshit");
* }
* else {
* printf("hit");
* }
* ```
*
* @param[in] hash Hash table to look into.
* @param[in] key Hash key to look for.
* @param[in] def Default value.
* @retval def `hash` does not have `key`.
* @retval otherwise The value associated with `key`.
*/
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def);
/**
* Identical to rb_hash_lookup(), except it yields the (implicitly) passed
* block instead of returning ::RUBY_Qnil.
*
* @param[in] hash Hash table to look into.
* @param[in] key Hash key to look for.
* @exception rb_eKeyError No block given.
* @return Either the value associated with the key, or what the block
* evaluates to if absent.
*/
VALUE rb_hash_fetch(VALUE hash, VALUE key);
/**
* Inserts or replaces ("upsert"s) the objects into the given hash table. This
* basically associates the given value with the given key. On duplicate key
* this function updates its associated value with the given one. Otherwise it
* inserts the association at the end of the table.
*
* @param[out] hash Target hash table to modify.
* @param[in] key Arbitrary Ruby object.
* @param[in] val A value to be associated with `key`.
* @exception rb_eFrozenError `hash` is frozen.
* @return The passed `val`
* @post `val` is associated with `key` in `hash`.
*/
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val);
/**
* Swipes everything out of the passed hash table.
*
* @param[out] hash Target to clear.
* @exception rb_eFrozenError `hash`is frozen.
* @return The passed `hash`
* @post `hash` has no contents.
*/
VALUE rb_hash_clear(VALUE hash);
/**
* Deletes each entry for which the block returns a truthy value. If there is
* no block given, it returns an enumerator that does the thing.
*
* @param[out] hash Target hash to modify.
* @exception rb_eFrozenError `hash` is frozen.
* @retval hash The hash is modified.
* @retval otherwise An instance of ::rb_cEnumerator that does it.
*/
VALUE rb_hash_delete_if(VALUE hash);
/**
* Deletes the passed key from the passed hash table, if any.
*
* @param[out] hash Target hash to modify.
* @param[in] key Key to delete.
* @retval RUBY_Qnil `hash` has no such key as `key`.
* @retval otherwise What was associated with `key`.
* @post `hash` has no such key as `key`.
*/
VALUE rb_hash_delete(VALUE hash, VALUE key);
/**
* Inserts a list of key-value pairs into a hash table at once. It is
* semantically identical to repeatedly calling rb_hash_aset(), but can be
* faster than that.
*
* @param[in] argc Length of `argv`, must be even.
* @param[in] argv A list of key, value, key, value, ...
* @param[out] hash Target hash table to modify.
* @post `hash` has contents from `argv`.
* @note `argv` is allowed to be NULL as long as `argc` is zero.
*
* @internal
*
* What happens for duplicated keys? Well it silently discards older ones to
* accept the newest (rightmost) one. This behaviour also mimics repeated call
* of rb_hash_aset().
*/
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash);
/**
* Type of callback functions to pass to rb_hash_update_by().
*
* @param[in] newkey A key of the table.
* @param[in] oldkey Value associated with `key` in hash1.
* @param[in] value Value associated with `key` in hash2.
* @return Either one of the passed values to take.
*/
typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);
/**
* Destructively merges two hash tables into one. It resolves key conflicts by
* calling the passed function and take its return value.
*
* @param[out] hash1 Target hash to be modified.
* @param[in] hash2 A hash to merge into `hash1`.
* @param[in] func Conflict reconciler.
* @exception rb_eFrozenError `hash1` is frozen.
* @exception rb_eRuntimeError `hash2` is updated instead.
* @return The passed `hash1`.
* @post Contents of `hash2` is merged into `hash1`.
* @note You can pass zero to `func`. This means values from `hash2`
* are always taken.
*/
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);
/* file.c */
/**
* This function is mysterious. What it does is not immediately obvious. Also
* what it does seems platform dependent.
*
* @param[in] path A local path.
* @retval 0 The "check" succeeded.
* @retval otherwise The "check" failed.
*/
int rb_path_check(const char *path);
/* hash.c */
/**
* Destructively removes every environment variables of the running process.
*
* @return The `ENV` object.
* @post The process has no environment variables.
*/
VALUE rb_env_clear(void);
/**
* Identical to #RHASH_SIZE(), except it returns the size in Ruby's integer
* instead of C's.
*
* @param[in] hash A hash object.
* @return The size of the hash.
*/
VALUE rb_hash_size(VALUE hash);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_HASH_H */
include/ruby/internal/intern/parse.h 0000644 00000014266 15040330603 0013551 0 ustar 00 #ifndef RBIMPL_INTERN_PARSE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PARSE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cSymbol.
*/
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* symbol.c */
/**
* Calculates an ID of attribute writer. For instance it returns `:foo=` when
* passed `:foo`.
*
* @param[in] id An id.
* @exception rb_eNameError `id` is not for attributes (e.g. operator).
* @return Calculated name of attribute writer.
*/
ID rb_id_attrset(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is a constant. In case an ID is in
* Unicode (likely), its "constant"-ness is determined if its first character
* is either upper case or title case. Otherwise it is detected if case-
* folding the first character changes its case or not.
*
* @param[in] id An id to classify.
* @retval 1 It is a constant.
* @retval 0 It isn't.
*/
int rb_is_const_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is a global variable. A global
* variable must start with `$`.
*
* @param[in] id An id to classify.
* @retval 1 It is a global variable.
* @retval 0 It isn't.
*/
int rb_is_global_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is an instance variable. An
* instance variable must start with `@`, but not `@@`.
*
* @param[in] id An id to classify.
* @retval 1 It is an instance variable.
* @retval 0 It isn't.
*/
int rb_is_instance_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is an attribute writer. An
* attribute writer is otherwise a local variable, except it ends with `=`.
*
* @param[in] id An id to classify.
* @retval 1 It is an attribute writer.
* @retval 0 It isn't.
*/
int rb_is_attrset_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is a class variable. A class
* variable is must start with `@@`.
*
* @param[in] id An id to classify.
* @retval 1 It is a class variable.
* @retval 0 It isn't.
*/
int rb_is_class_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is a local variable. A local
* variable starts with a lowercase character, followed by some alphanumeric
* characters or `_`, then ends with anything other than `!`, `?`, or `=`.
*
* @param[in] id An id to classify.
* @retval 1 It is a local variable.
* @retval 0 It isn't.
*/
int rb_is_local_id(ID id);
RBIMPL_ATTR_CONST()
/**
* Classifies the given ID, then sees if it is a junk ID. An ID with no
* special syntactic structure is considered junk. This category includes for
* instance punctuation.
*
* @param[in] id An id to classify.
* @retval 1 It is a junk.
* @retval 0 It isn't.
*/
int rb_is_junk_id(ID);
RBIMPL_ATTR_NONNULL(())
/**
* Sees if the passed C string constructs a valid syntactic symbol. Invalid
* ones for instance includes whitespaces.
*
* @param[in] str A C string to check.
* @retval 1 It is a valid symbol name.
* @retval 0 It is invalid as a symbol name.
*/
int rb_symname_p(const char *str);
/* vm.c */
/**
* Queries the last match, or `Regexp.last_match`, or the `$~`. You don't have
* to use it, because in reality you can get `$~` using rb_gv_get() as usual.
*
* @retval RUBY_Qnil The method has not ran a regular expression.
* @retval otherwise An instance of ::rb_cMatch.
*/
VALUE rb_backref_get(void);
/**
* Updates `$~`. You don't have to use it, because in reality you can set `$~`
* using rb_gv_set() as usual.
*
* @param[in] md Arbitrary Ruby object.
* @post The passed object is assigned to `$~`.
*
* @internal
*
* Yes, this function bypasses the Check_Type() that would normally prevent
* evil souls from assigning evil objects to `$~`. Use of this function is a
* really bad smell.
*/
void rb_backref_set(VALUE md);
/**
* Queries the last line, or the `$_`. You don't have to use it, because in
* reality you can get `$_` using rb_gv_get() as usual.
*
* @retval RUBY_Qnil There has never been a "line" yet.
* @retval otherwise The last set `$_` value.
*/
VALUE rb_lastline_get(void);
/**
* Updates `$_`. You don't have to use it, because in reality you can set `$_`
* using rb_gv_set() as usual.
*
* @param[in] str Arbitrary Ruby object.
* @post The passed object is assigned to `$_`.
*
* @internal
*
* Unlike `$~`, you can assign non-strings to `$_`, even from ruby scripts.
*/
void rb_lastline_set(VALUE str);
/* symbol.c */
/**
* Collects every single bits of symbols that have ever interned in the entire
* history of the current process.
*
* @return An array that contains all symbols that have ever existed.
*/
VALUE rb_sym_all_symbols(void);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_PARSE_H */
include/ruby/internal/intern/io.h 0000644 00000064364 15040330603 0013052 0 ustar 00 #ifndef RBIMPL_INTERN_IO_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_IO_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cIO.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* io.c */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define rb_defout rb_stdout
/* string.c */ /* ...why? moved in commit de7161526014b781468cea5d84411e23be */
/**
* The field separator character for inputs, or the `$;`. This affects how
* `String#split` works. You can set this via the `-F` command line option.
* You can also assign arbitrary ruby objects programmatically, but it makes
* best sense for you to assign a regular expression here.
*
* @internal
*
* Tidbit: "fs" comes from AWK's `FS` variable.
*/
RUBY_EXTERN VALUE rb_fs;
/* io.c */ /* ...why? given rb_fs is in string.c? */
/**
* The field separator character for outputs, or the `$,`. This affects how
* `Array#join` works.
*
* @deprecated Assigning anything other than ::RUBY_Qnil to this variable is
* deprecated.
*/
RUBY_EXTERN VALUE rb_output_fs;
/**
* The record separator character for inputs, or the `$/`. This affects how
* `IO#gets` works. You can set this via the `-0` command line option.
*
* @deprecated Assigning anything other than ::RUBY_Qnil to this variable is
* deprecated.
*
* @internal
*
* Tidbit: "rs" comes from AWK's `RS` variable.
*/
RUBY_EXTERN VALUE rb_rs;
/**
* This is the default value of ::rb_rs, i.e. `"\n"`. It seems it has always
* been just a newline string since the beginning. Not sure why C codes has to
* use this, given there is no way for ruby programs to interface.
*
* Also it has not been deprecated for unknown reasons.
*/
RUBY_EXTERN VALUE rb_default_rs;
/**
* The record separator character for outputs, or the `$\`. This affects how
* `IO#print` works.
*
* @deprecated Assigning anything other than ::RUBY_Qnil to this variable is
* deprecated.
*/
RUBY_EXTERN VALUE rb_output_rs;
/**
* Writes the given string to the given IO.
*
* @param[out] io An IO, opened for writing.
* @param[in] str A String-like object to write to `io`.
* @exception rb_eIOError `io` isn't opened for writing.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `str` to String.
* @exception rb_eSystemCallError `write(2)` failed for some reason.
* @return The number of bytes written to the `io`.
* @post `str` (up to the length of return value) is written to `io`.
* @note This function blocks.
* @note Partial write is a thing. It must be at least questionable not
* to check the return value.
*
* @internal
*
* Above description is in fact inaccurate. This function can take arbitrary
* objects, and calls their `write` method. What is written above in fact
* describes how `IO#write` works. You can pass StringIO etc. here, and would
* work completely differently.
*/
VALUE rb_io_write(VALUE io, VALUE str);
/**
* Reads a "line" from the given IO. A line here means a chunk of characters
* which is terminated by either `"\n"` or an EOF.
*
* @param[in,out] io An IO, opened for reading.
* @exception rb_eIOError `io` isn't opened for reading.
* @exception rb_eFrozenError `io` is frozen.
* @retval RUBY_Qnil `io` is at EOF.
* @retval otherwise An instance of ::rb_cString.
* @post `io` is read.
* @note Unlike `IO#gets` it doesn't set `$_`.
* @note Unlike `IO#gets` it doesn't consider `$/`.
*/
VALUE rb_io_gets(VALUE io);
/**
* Reads a byte from the given IO.
*
* @note In Ruby a "byte" always means an 8 bit integer ranging from
* 0 to 255 inclusive.
* @param[in,out] io An IO, opened for reading.
* @exception rb_eIOError `io` is not opened for reading.
* @exception rb_eFrozenError `io` is frozen.
* @retval RUBY_Qnil `io` is at EOF.
* @retval otherwise An instance of ::rb_cInteger.
* @post `io` is read.
*
* @internal
*
* Of course there was a function called `rb_io_getc()`. It was removed in
* commit a25fbe3b3e531bbe479f344af24eaf9d2eeae6ea.
*/
VALUE rb_io_getbyte(VALUE io);
/**
* "Unget"s a string. This function pushes back the passed string onto the
* passed IO, such that a subsequent buffered read will return it. If the
* passed content is in fact an integer, a single character string of that
* codepoint of the encoding of the IO will be pushed back instead.
*
* It might be counter-intuitive but this function can push back multiple
* characters at once. Also this function can be called multiple times on a
* same IO. Also a "character" can be wider than a byte, depending on the
* encoding of the IO.
*
* @param[out] io An IO, opened for reading.
* @param[in] c Either a String, or an Integer.
* @exception rb_eIOError `io` is not opened for reading.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `c` to ::rb_cString.
* @return Always returns ::RUBY_Qnil.
*
* @internal
*
* Why there is ungetc, given there is no getc?
*/
VALUE rb_io_ungetc(VALUE io, VALUE c);
/**
* Identical to rb_io_ungetc(), except it doesn't take the encoding of the
* passed IO into account. When an integer is passed, it just casts that value
* to C's `unsigned char`, and pushes that back.
*
* @param[out] io An IO, opened for reading.
* @param[in] b Either a String, or an Integer.
* @exception rb_eIOError `io` is not opened for reading.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `b` to ::rb_cString.
* @return Always returns ::RUBY_Qnil.
*/
VALUE rb_io_ungetbyte(VALUE io, VALUE b);
/**
* Closes the IO. Any buffered contents are flushed to the operating system.
* Any future operations against the IO would raise ::rb_eIOError. In case the
* io was created using `IO.popen`, it also sets the `$?`.
*
* @param[out] io Target IO to close.
* @return Always returns ::RUBY_Qnil.
* @post `$?` is set in case IO is a pipe.
* @post No operations are possible against `io` any further.
* @note This can block to flush the contents.
* @note This can wake other threads up, especially those who are
* `select()`-ing the passed IO.
* @note Multiple invocations of this function over the same IO again
* and again is not an error, since Ruby 2.3.
*
* @internal
*
* You can close a frozen IO... Is this intentional?
*/
VALUE rb_io_close(VALUE io);
/**
* Flushes any buffered data within the passed IO to the underlying operating
* system.
*
* @param[out] io Target IO to flush.
* @exception rb_eIOError `io` is closed.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eSystemCallError `write(2)` failed for some reason.
* @return The passed `io`.
* @post `io`'s buffers are empty.
* @note This operation also discards the read buffer. Should basically
* be harmless, but in an esoteric situation like when user pushed
* something different from what was read using `ungetc`, this
* operation in fact changes the behaviour of the `io`.
* @note Buffering is difficult. This operation flushes the data from
* our userspace to the kernel, but that doesn't always mean you
* can expect them stored persistently onto your hard drive.
*/
VALUE rb_io_flush(VALUE io);
/**
* Queries if the passed IO is at the end of file. "The end of file" here mans
* that there are no more data to read. This function blocks until the read
* buffer is filled in, and if that operation reached the end of file, it still
* returns ::RUBY_Qfalse (because there are data yet in that buffer). It
* returns ::RUBY_Qtrue once after the buffer is cleared.
*
* @param[in,out] io Target io to query.
* @exception rb_eIOError `io` is not opened for reading.
* @exception rb_eFrozenError `io` is frozen.
* @retval RUBY_Qfalse There are things yet to be read.
* @retval RUBY_Qtrue "The end of file" situation.
*/
VALUE rb_io_eof(VALUE io);
/**
* Sets the binmode. This operation nullifies the effect of textmode (newline
* conversion from `"\r\n"` to `"\n"` or vice versa). Note that it doesn't
* stop character encodings conversions. For instance an IO created using:
*
* ```ruby
* File.open(
* "/dev/urandom",
* textmode: true,
* external_encoding: Encoding::GB18030,
* internal_encoding: Encoding::Windows_31J)
* ```
*
* has both newline and character conversions. If you pass such IO to this
* function, only the `textmode:true` part is cancelled. Texts read through
* the IO would still be encoded in Windows-31J; texts written to the IO will
* be encoded in GB18030.
*
* @param[out] io Target IO to modify.
* @exception rb_eFrozenError `io` is frozen.
* @return The passed `io`.
* @post `io` is in binmode.
* @note There is no equivalent operation in Ruby. You can do this only
* in C.
*/
VALUE rb_io_binmode(VALUE io);
/**
* Forces no conversions be applied to the passed IO. Unlike rb_io_binmode(),
* this cancels any newline conversions as well as encoding conversions. Any
* texts read/written through the IO will be the verbatim binary contents.
*
* @param[out] io Target IO to modify.
* @exception rb_eFrozenError `io` is frozen.
* @return The passed `io`.
* @post `io` is in binmode. Both external/internal encoding are set to
* rb_ascii8bit_encoding().
* @note This is the implementation of `IO#binmode`.
*/
VALUE rb_io_ascii8bit_binmode(VALUE io);
/**
* Identical to rb_io_write(), except it always returns the passed IO.
*
* @param[out] io An IO, opened for writing.
* @param[in] str A String-like object to write to `io`.
* @exception rb_eIOError `io` isn't opened for writing.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `str` to String.
* @exception rb_eSystemCallError `write(2)` failed.
* @return The passed `io`.
* @post `str` is written to `io`.
* @note This function blocks.
*
* @internal
*
* As rb_io_write(), above description is a fake.
*/
VALUE rb_io_addstr(VALUE io, VALUE str);
/**
* This is a rb_f_sprintf() + rb_io_write() combo.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv A format string followed by its arguments.
* @param[out] io An IO, opened for writing.
* @exception rb_eIOError `io` isn't opened for writing.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `str` to String.
* @exception rb_eSystemCallError `write(2)` failed.
* @return Always returns ::RUBY_Qnil.
* @post `argv` is formatted, then written to `io`.
* @note This function blocks.
*
* @internal
*
* As rb_io_write(), above descriptions include fakes.
*/
VALUE rb_io_printf(int argc, const VALUE *argv, VALUE io);
/**
* Iterates over the passed array to apply rb_io_write() individually. If
* there is `$,`, this function inserts the string in middle of each
* iterations. If there is `$\`, this function appends the string at the end.
* If the array is empty, this function outputs `$_`.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv An array of strings to display.
* @param[out] io An IO, opened for writing.
* @exception rb_eIOError `io` isn't opened for writing.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `str` to String.
* @exception rb_eSystemCallError `write(2)` failed.
* @return Always returns ::RUBY_Qnil.
* @post `argv` is written to `io`.
* @note This function blocks.
* @note This function calls rb_io_write() multiple times. Which means,
* it is not an atomic operation. Outputs from multiple threads
* can interleave.
*
* @internal
*
* As rb_io_write(), above descriptions include fakes.
*/
VALUE rb_io_print(int argc, const VALUE *argv, VALUE io);
/**
* Iterates over the passed array to apply rb_io_write() individually. Unlike
* rb_io_print(), this function prints a newline per each element. It also
* flattens the passed array (OTOH rb_io_print() just resorts to
* rb_ary_to_s()).
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv An array of strings to display.
* @param[out] io An IO, opened for writing.
* @exception rb_eIOError `io` isn't opened for writing.
* @exception rb_eFrozenError `io` is frozen.
* @exception rb_eTypeError No conversion from `str` to String.
* @exception rb_eSystemCallError `write(2)` failed.
* @return Always returns ::RUBY_Qnil.
* @post `argv` is written to `io`.
* @note This function blocks.
* @note This function calls rb_io_write() multiple times. Which means,
* it is not an atomic operation. Outputs from multiple threads
* can interleave.
*
* @internal
*
* As rb_io_write(), above descriptions include fakes.
*/
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE io);
/**
* Creates an IO instance whose backend is the given file descriptor. C
* extension libraries sometimes have file descriptors created elsewhere (maybe
* deep inside of another shared library), which they want ruby programs to
* handle. This function is handy for such situations.
*
* @param[in] fd Target file descriptor.
* @param[in] flags Flags, e.g. `O_CREAT|O_EXCL`
* @param[in] path The path of the file that backs `fd`, for diagnostics.
* @return An allocated instance of ::rb_cIO.
* @note Leave `path` NULL if you don't know.
*/
VALUE rb_io_fdopen(int fd, int flags, const char *path);
RBIMPL_ATTR_NONNULL(())
/**
* Opens a file located at the given path.
*
* `fmode` is a C string that represents the open mode. It can be one of:
*
* - `r` (means `O_RDONLY`),
* - `w` (means `O_WRONLY | O_TRUNC | O_CREAT`),
* - `a` (means `O_WRONLY | O_APPEND | O_CREAT`),
*
* Followed by zero or more combinations of:
*
* - `b` (means `_O_BINARY`),
* - `t` (means `_O_TEXT`),
* - `+` (means `O_RDWR`),
* - `x` (means `O_TRUNC`), or
* - `:[BOM|]enc[:enc]` (see below).
*
* This last one specifies external (and internal if any) encodings,
* respectively. If optional `BOM|` is specified and the specified external
* encoding is capable of expressing BOMs, opening file's contents' byte order
* is auto-detected using the mechanism.
*
* So for instance, fmode of `"rt|BOM:utf-16le:utf-8"` specifies that...
*
* - the physical representation of the contents of the file is in UTF-16;
* - honours its BOM but assumes little endian if absent;
* - opens the file for reading;
* - what is read is converted into UTF-8;
* - with newlines cannibalised to `\n`.
*
* @param[in] fname Path to open.
* @param[in] fmode Mode specifier much like `fopen(3)`.
* @exception rb_eArgError `fmode` contradicted (e.g. `"bt"`).
* @exception rb_eSystemCallError `open(2)` failed for some reason.
* @return An instance of ::rb_cIO.
*/
VALUE rb_file_open(const char *fname, const char *fmode);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_file_open(), except it takes the pathname as a Ruby's string
* instead of C's. In case the passed Ruby object is a non-String it tries to
* call `#to_path`.
*
* @param[in] fname Path to open.
* @param[in] fmode Mode specifier much like `fopen(3)`.
* @exception rb_eTypeError `fname` is not a String.
* @exception rb_eEncCompatError `fname` is not ASCII-compatible.
* @exception rb_eArgError `fmode` contradicted (e.g. `"bt"`).
* @exception rb_eSystemCallError `open(2)` failed for some reason.
* @return An instance of ::rb_cIO.
*/
VALUE rb_file_open_str(VALUE fname, const char *fmode);
/**
* Much like rb_io_gets(), but it reads from the mysterious ARGF object. ARGF
* in this context can be seen as a virtual IO which concatenates contents of
* the files passed to the process via the ARGV, or just STDIN if there are no
* such files.
*
* Unlike rb_io_gets() this function sets `$_`.
*
* @exception rb_eFrozenError ARGF resorts to STDIN but it is frozen.
* @retval RUBY_Qnil ARGF is at EOF.
* @retval otherwise An instance of ::rb_cString.
* @post ARGF is read.
* @post `$_` is set.
*
* @internal
*
* In reality, this function can call `ARGF.gets`. Its redefinition can affect
* the behaviour.
*
* Also, you can tamper ARGV on-the-fly in middle of ARGF usages:
*
* ```
* gets # Reads the first file.
* ARGV << '/proc/self/limits' # Adds a file.
* gets # Can read from /proc/self/limits.
* ```
*/
VALUE rb_gets(void);
RBIMPL_ATTR_NONNULL(())
/**
* Writes the given error message to somewhere applicable. On Windows it goes
* to the console. On POSIX environments it goes to the standard error.
*
* @warning IT IS A BAD IDEA to use this function form your C extensions.
* It is often annoying when GUI applications write to consoles;
* users don't want to look at there. Programmers also want to
* control the cause of the message itself, like by rescuing an
* exception. Just let ruby handle errors. That must be better than
* going your own way.
*
* @param[in] str Error message to display.
* @post `str` is written to somewhere.
*
* @internal
*
* AFAIK this function is listed here without marked deprecated because there
* are usages of this function in the wild.
*/
void rb_write_error(const char *str);
/**
* Identical to rb_write_error(), except it additionally takes the message's
* length. Necessary when you want to handle wide characters.
*
* @param[in] str Error message to display.
* @param[in] len Length of `str`, in bytes.
* @post `str` is written to somewhere.
*/
void rb_write_error2(const char *str, long len);
/**
* Closes everything. In case of POSIX environments, a child process inherits
* its parent's opened file descriptors. Which is nowadays considered as one
* of the UNIX mistakes. This function closes such inherited file descriptors.
* When your C extension needs to have a child process, don't forget to call
* this from your child process right before exec.
*
* @param[in] lowfd Lower bound of FDs (you want STDIN to remain, no?).
* @param[in] maxhint Hint of max FDs.
* @param[in] noclose_fds A hash, whose keys are an allowlist.
*
* @internal
*
* As of writing, in spite of the name, this function does not actually close
* anything. It just sets `FD_CLOEXEC` for everything and let `execve(2)` to
* atomically close them at once. This is because as far as we know there are
* no such platform that has `fork(2)` but lacks `FD_CLOEXEC`.
*
* Because this function is expected to run on a forked process it is entirely
* async-signal-safe.
*/
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
RBIMPL_ATTR_NONNULL(())
/**
* This is an rb_cloexec_pipe() + rb_update_max_fd() combo.
*
* @param[out] pipes Return buffer. Must at least hold 2 elements.
* @retval 0 Successful creation of a pipe.
* @retval -1 Failure in underlying system call(s).
* @post `pipes` is filled with file descriptors.
* @post `errno` is set on failure.
*/
int rb_pipe(int *pipes);
/**
* Queries if the given FD is reserved or not. Occasionally Ruby interpreter
* opens files for its own purposes. Use this function to prevent touching
* such behind-the-scene descriptors.
*
* @param[in] fd Target file descriptor.
* @retval 1 `fd` is reserved.
* @retval 0 Otherwise.
*/
int rb_reserved_fd_p(int fd);
/** @alias{rb_reserved_fd_p} */
#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd)
/**
* Opens a file that closes on exec. In case of POSIX environments, a child
* process inherits its parent's opened file descriptors. Which is nowadays
* considered as one of the UNIX mistakes. This function opens a file
* descriptor as `open(2)` does, but additionally instructs the operating
* system that we don't want it be seen from child processes.
*
* @param[in] pathname File path to open.
* @param[in] flags Open mode, as in `open(2)`.
* @param[in] mode File mode, in case of `O_CREAT`.
* @retval -1 `open(2)` failed for some reason.
* @retval otherwise An allocated new file descriptor.
* @note This function does not raise.
*
* @internal
*
* Whether this function can take NULL or not depends on the underlying open(2)
* system call implementation but @shyouhei doesn't think it's worth trying.
*/
int rb_cloexec_open(const char *pathname, int flags, mode_t mode);
/**
* Identical to rb_cloexec_fcntl_dupfd(), except it implies minfd is 3.
*
* @param[in] oldfd File descriptor to duplicate.
* @retval -1 `dup2(2)` failed for some reason.
* @retval otherwise An allocated new file descriptor.
* @note This function does not raise.
*/
int rb_cloexec_dup(int oldfd);
/**
* Identical to rb_cloexec_dup(), except you can specify the destination file
* descriptor. If the destination is already squatted by another file
* descriptor that gets silently closed without any warnings. (This is a spec
* requested by POSIX.)
*
* @param[in] oldfd File descriptor to duplicate.
* @param[in] newfd Return value destination.
* @retval -1 `dup2(2)` failed for some reason.
* @retval newfd An allocated new file descriptor.
* @post Whatever sat at `newfd` gets closed with no notifications.
* @post In case return value is -1 `newfd` is untouched.
* @note This function does not raise.
*/
int rb_cloexec_dup2(int oldfd, int newfd);
RBIMPL_ATTR_NONNULL(())
/**
* Opens a pipe with closing on exec. In case of POSIX environments, a child
* process inherits its parent's opened file descriptors. Which is nowadays
* considered as one of the UNIX mistakes. This function opens a pipe as
* `pipe(2)` does, but additionally instructs the operating system that we
* don't want the duplicated FDs be seen from child processes.
*
* @param[out] fildes Return buffer. Must at least hold 2 elements.
* @retval 0 Successful creation of a pipe.
* @retval -1 Failure in underlying system call(s).
* @post `pipes` is filled with file descriptors.
* @post `errno` is set on failure.
*/
int rb_cloexec_pipe(int fildes[2]);
/**
* Duplicates a file descriptor with closing on exec. In case of POSIX
* environments, a child process inherits its parent's opened file descriptors.
* Which is nowadays considered as one of the UNIX mistakes. This function
* duplicates a file descriptor as `dup(2)` does, but additionally instructs
* the operating system that we don't want the duplicated FD be seen from child
* processes.
*
* @param[in] fd File descriptor to duplicate.
* @param[in] minfd Minimum allowed FD to return.
* @retval -1 `dup(2)` failed for some reason.
* @retval otherwise An allocated new file descriptor.
* @note This function does not raise.
*
* `minfd` is handy when for instance STDERR is closed but you don't want to
* use fd 2.
*/
int rb_cloexec_fcntl_dupfd(int fd, int minfd);
/**
* Informs the interpreter that the passed fd can be the max. This information
* is used from rb_close_before_exec().
*
* @param[in] fd An open FD, which can be large.
*/
void rb_update_max_fd(int fd);
/**
* Sets or clears the close-on-exec flag of the passed file descriptor to the
* desired state. STDIN, STDOUT, STDERR are the exceptional file descriptors
* that shall remain open. All others are to be closed on exec. When a C
* extension library opens a file descriptor using anything other than
* rb_cloexec_open() etc., that file descriptor shall experience this function.
*
* @param[in] fd An open file descriptor.
*/
void rb_fd_fix_cloexec(int fd);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_IO_H */
include/ruby/internal/intern/dir.h 0000644 00000003626 15040330603 0013213 0 ustar 00 #ifndef RBIMPL_INTERN_DIR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_DIR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cDir.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* dir.c */
/**
* Queries the path of the current working directory of the current process.
*
* @return An instance of ::rb_cString that holds the working directory.
* @note The returned string is in "filesystem" encoding. Most notably on
* Linux this is an alias of default external encoding. Most notably
* on Windows it can be an alias of OS codepage.
*/
VALUE rb_dir_getwd(void);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_DIR_H */
include/ruby/internal/intern/numeric.h 0000644 00000016770 15040330603 0014103 0 ustar 00 #ifndef RBIMPL_INTERN_NUMERIC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_NUMERIC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cNumeric.
*/
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RB_NUM_COERCE_FUNCS_NEED_OPID 1
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* numeric.c */
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
/**
* Just always raises an exception.
*
* @exception rb_eZeroDivError Division by zero error.
*/
void rb_num_zerodiv(void);
/**
* @name Coercion operators.
*
* What is a coercion? Well Ruby is basically an OOPL but it also has
* arithmetic operators. They are implemented in OO manners. For instance
* `a+b` is a binary operation `+`, whose receiver is `a`, and whose (sole)
* argument is `b`.
*
* The problem is, you often want `a+b == b+a` to hold. That is easy if both
* `a` and `b` belongs to the same class... Ensuring `1 + 2 == 2 + 1` is kind
* of intuitive. But if you want `1.0 + 2 == 2 + 1.0`, things start getting
* complicated. `1.0+2` is `Float#+`, while `2+1.0` is `Integer#+`. In order
* to achieve the equality Float's and Integer's methods must agree with their
* behaviours.
*
* Now. Floats versus Integers situation is still controllable because they
* are both built-in. But in Ruby you can define your own numeric classes.
* BigDecimal, which is a rubygems gem distributed along with the interpreter,
* is one of such examples. Rational was another such example before. In
* short you cannot create list of all possible combination of the classes that
* could be the operand of `+` operator. Then how do we achieve the
* commutativity?
*
* Here comes the concept of coercion. If a definition of an operator
* encounters an object which is unknown to the author, just assumes that the
* unknown object knows how to handle the situation. So for instance when
* `1+x` has unknown `x`, it lets the `x` handle this.
*
* ```ruby
* class Foo
* def +(x)
* if we_know_what_is_x? then
* ... # handle here
* else
* y, z = x.coerce self
* return y + z
* end
* end
* end
* ```
*
* The `x.coerce` method returns a 2-element array which are "casted" versions
* of `x` and `self`.
*
* @{
*/
/**
* Coerced binary operation. This function first coerces the two objects, then
* applies the operation.
*
* @param[in] lhs LHS operand.
* @param[in] rhs RHS operand.
* @param[in] op Operator method name.
* @exception rb_eTypeError Coercion failed for some reason.
* @return `lhs op rhs`, in a coerced way.
*/
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op);
/**
* Identical to rb_num_coerce_bin(), except for return values. This function
* best suits for comparison operators e.g. `<=>`.
*
* @param[in] lhs LHS operand.
* @param[in] rhs RHS operand.
* @param[in] op Operator method name.
* @retval RUBY_Qnil Coercion failed for some reason.
* @retval otherwise `lhs op rhs`, in a coerced way.
*/
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op);
/**
* Identical to rb_num_coerce_cmp(), except for return values. This function
* best suits for relationship operators e.g. `<=`.
*
* @param[in] lhs LHS operand.
* @param[in] rhs RHS operand.
* @param[in] op Operator method name.
* @exception rb_eArgError Coercion failed for some reason.
* @return `lhs op rhs`, in a coerced way.
*/
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op);
/**
* This one is optimised for bitwise operations, but the API is identical to
* rb_num_coerce_bin().
*
* @param[in] lhs LHS operand.
* @param[in] rhs RHS operand.
* @param[in] op Operator method name.
* @exception rb_eArgError Coercion failed for some reason.
* @return `lhs op rhs`, in a coerced way.
*/
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op);
/** @} */
/**
* Converts a numeric value into a Fixnum. This is not a preserving
* conversion; for instance 1.5 would be converted into 1.
*
* @param[in] val A numeric object.
* @exception rb_eTypeError No conversion from `val` to Integer.
* @exception rb_eRangeError `val` out of range.
* @return A fixnum converted from `val`.
*
* @internal
*
* This seems used from nowhere?
*/
VALUE rb_num2fix(VALUE val);
/**
* Generates a place-value representation of the given Fixnum, with given
* radix.
*
* @param[in] val A fixnum to stringify.
* @param[in] base `2` to `36` inclusive for each radix.
* @exception rb_eArgError `base` is out of range.
* @return An instance of ::rb_cString representing `val`.
* @pre `val` must be a Fixnum (no checks performed).
*/
VALUE rb_fix2str(VALUE val, int base);
RBIMPL_ATTR_CONST()
/**
* Compares two `double`s. Handy when implementing a spaceship operator.
*
* @param[in] lhs A value.
* @param[in] rhs Another value.
* @retval RB_INT2FIX(-1) `lhs` is "bigger than" `rhs`.
* @retval RB_INT2FIX(1) `rhs` is "bigger than" `lhs`.
* @retval RB_INT2FIX(0) They are equal.
* @retval RUBY_Qnil Not comparable, e.g. NaN.
*/
VALUE rb_dbl_cmp(double lhs, double rhs);
/**
* Raises the passed `x` to the power of `y`.
*
* @note The return value can be really big.
* @note Also the return value can be really small, in case `x` is a
* negative number.
* @param[in] x A number.
* @param[in] y Another number.
* @retval Inf Cannot express the result.
* @retval 1 Either `y` is 0 or `x` is 1.
* @retval otherwise An instance of ::rb_cInteger whose value is `x ** y`.
*
* @internal
*
* This function returns Infinity when `y` is big enough not to fit into a
* Fixnum. Warning is issued then.
*/
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_NUMERIC_H */
include/ruby/internal/intern/rational.h 0000644 00000014533 15040330603 0014245 0 ustar 00 #ifndef RBIMPL_INTERN_RATIONAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RATIONAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cRational.
*/
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* rational.c */
/**
* Identical to rb_rational_new(), except it skips argument validations. It is
* thus dangerous for extension libraries. For instance `1/0r` could be
* constructed using this.
*
* @param[in] num Numerator, an instance of ::rb_cInteger.
* @param[in] den Denominator, an instance of ::rb_cInteger.
* @exception rb_eTypeError Either argument is not an Integer.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*/
VALUE rb_rational_raw(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. As `x` is already an Integer, it practically
* converts it into a Rational of the identical value.
*
* @param[in] x An instance of ::rb_cInteger.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))
/** @alias{rb_rational_raw} */
#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))
/**
* Constructs a Rational, with reduction. This returns for instance `(2/3)r`
* for `rb_rational_new(INT2NUM(-384), INT2NUM(-576))`.
*
* @param[in] num Numerator, an instance of ::rb_cInteger.
* @param[in] den Denominator, an instance of ::rb_cInteger.
* @exception rb_eZeroDivError `den` is zero.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*/
VALUE rb_rational_new(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. As `x` is already an Integer, it practically
* converts it into a Rational of the identical value.
*
* @param[in] x An instance of ::rb_cInteger.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))
/** @alias{rb_rational_new} */
#define rb_rational_new2(x,y) rb_rational_new((x), (y))
/**
* Converts various values into a Rational. This function accepts:
*
* - Instances of ::rb_cInteger (taken as-is),
* - Instances of ::rb_cRational (taken as-is),
* - Instances of ::rb_cFloat (applies `#to_r`),
* - Instances of ::rb_cComplex (applies `#to_r`),
* - Instances of ::rb_cString (applies `#to_r`),
* - Other objects that respond to `#to_r`.
*
* It (possibly recursively) applies `#to_r` until both sides become either
* Integer or Rational, then divides them.
*
* As a special case, passing ::RUBY_Qundef to `den` is the same as passing
* `RB_INT2NUM(1)`.
*
* @param[in] num Numerator (see above).
* @param[in] den Denominator (see above).
* @exception rb_eTypeError Passed something not described above.
* @exception rb_eFloatDomainError `#to_r` produced Nan/Inf.
* @exception rb_eZeroDivError `#to_r` produced zero for `den`.
* @return An instance of ::rb_cRational whose value is `(num/den)r`.
*
* @internal
*
* This was the implementation of `Kernel#Rational` before, but they diverged.
*/
VALUE rb_Rational(VALUE num, VALUE den);
/**
* Shorthand of `(x/1)r`. It practically converts it into a Rational of the
* identical value.
*
* @param[in] x ::rb_cInteger, ::rb_cRational, or something that responds to
* `#to_r`.
* @return An instance of ::rb_cRational, whose value is `(x/1)r`.
*/
#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))
/** @alias{rb_Rational} */
#define rb_Rational2(x,y) rb_Rational((x), (y))
RBIMPL_ATTR_PURE()
/**
* Queries the numerator of the passed Rational.
*
* @param[in] rat An instance of ::rb_cRational.
* @return Its numerator part, which is an instance of ::rb_cInteger.
*/
VALUE rb_rational_num(VALUE rat);
RBIMPL_ATTR_PURE()
/**
* Queries the denominator of the passed Rational.
*
* @param[in] rat An instance of ::rb_cRational.
* @return Its denominator part, which is an instance of ::rb_cInteger
* greater than or equal to one..
*/
VALUE rb_rational_den(VALUE rat);
/**
* Simplified approximation of a float. It returns a rational `rat` which
* satisfies:
*
* ```
* flt - |prec| <= rat <= flt + |prec|
* ```
*
* ```ruby
* 3.141592.rationalize(0.001) # => (201/64)r
* 3.141592.rationalize(0.01)' # => (22/7)r
* 3.141592.rationalize(0.1)' # => (16/5)r
* 3.141592.rationalize(1)' # => (3/1)r
* ```
*
* @param[in] flt An instance of ::rb_cFloat to rationalise.
* @param[in] prec Another ::rb_cFloat, which is the "precision".
* @return Approximation of `flt`, in ::rb_cRational.
*/
VALUE rb_flt_rationalize_with_prec(VALUE flt, VALUE prec);
/**
* Identical to rb_flt_rationalize_with_prec(), except it auto-detects
* appropriate precision depending on the passed value.
*
* @param[in] flt An instance of ::rb_cFloat to rationalise.
* @return Approximation of `flt`, in ::rb_cRational.
*/
VALUE rb_flt_rationalize(VALUE flt);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RATIONAL_H */
include/ruby/internal/intern/process.h 0000644 00000026012 15040330603 0014105 0 ustar 00 #ifndef RBIMPL_INTERN_PROCESS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PROCESS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_mProcess.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/config.h" /* rb_pid_t is defined here. */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* process.c */
/**
* Sets the "last status", or the `$?`.
*
* @param[in] status The termination status, as defined in `waitpid(3posix)`.
* @param[in] pid The last child of the current process.
* @post `$?` is updated.
*/
void rb_last_status_set(int status, rb_pid_t pid);
/**
* Queries the "last status", or the `$?`.
*
* @retval RUBY_Qnil The current thread has no dead children.
* @retval otherwise An instance of Process::Status describing the status of
* the child that was most recently `wait`-ed.
*/
VALUE rb_last_status_get(void);
RBIMPL_ATTR_NONNULL(())
/**
* Executes a shell command.
*
* @warning THIS FUNCTION RETURNS on error!
* @param[in] cmd Passed to the shell.
* @retval -1 Something prevented the command execution.
* @post Upon successful execution this function doesn't return.
* @post In case it returns the `errno` is set properly.
*/
int rb_proc_exec(const char *cmd);
RBIMPL_ATTR_NORETURN()
/**
* Replaces the current process by running the given external command. This is
* the implementation of `Kernel#exec`.
*
* @param[in] argc Number of objects in `argv`.
* @param[in] argv Command and its options to execute.
* @exception rb_eTypeError Invalid options e.g. non-String argv.
* @exception rb_eArgError Invalid options e.g. redirection cycle.
* @exception rb_eNotImpError Not implemented e.g. no `setuid(2)`.
* @exception rb_eRuntimeError `Process::UID.switch` in operation.
* @exception rb_eSystemCallError `execve(2)` failed.
* @warning This function doesn't return.
* @warning On failure it raises. On success the process is replaced.
*
* @internal
*
* @shyouhei have to say that the rdoc for `Kernel#exec` is fairly incomplete.
* AFAIK this function ultimately takes the following signature:
*
* ```rbs
* type boolx = bool | nil # != `boolish`
*
* type rlim_t = Integer # rlim_cur
* | [ Integer, Integer ] # rlim_cur, rlim_max
*
* type uid_t = String # e.g. "root"
* | Integer # e.g. 0
*
* type gid_t = String # e.g. "wheel"
* | Integer # e.g. 0
*
* type fmode = String # e.g. "rb"
* | Integer # e.g. O_RDONLY | O_BINARY
*
* type mode_t = Integer # e.g. 0644
*
* type pgrp = true # Creates a dedicated pgroup
* | 0 # ditto
* | nil # Uses the current one
* | Integer # Uses this specific pgroup
*
* type fd = :in # STDIN
* | :out # STDOUT
* | :err # STDERR
* | IO # This specific IO
* | Integer # A file descriptor of this #
*
* type src = fd | [ fd ]
* type dst = :close # Intuitive
* | fd # Intuitive
* | String # Open a file at this path
* | [ String ] # ... using O_RDONLY
* | [ String, fmode ] # ... using this mode
* | [ String, fmode, mode_t ] # ... with a permission
* | [ :child, fd ] # fd of child side
*
* type redir = Hash[ src, dst ]
*
* # ----
*
* # Key-value pair of environment variables
* type envp = Hash[ String, String ]
*
* # Actual name (and the name passed to the subprocess if any)
* type arg0 = String | [ String, String ]
*
* # Arbitrary string parameters
* type argv = String
*
* # Exec options:
* type argh = redir | {
* chdir: String, # Working directory
* close_others: boolx, # O_CLOEXEC like behaviour
* gid: gid_t, # setegid(2)
* pgrooup: pgrp, # setpgrp(2)
* rlimit_as: rlim_t, # setrlimit(2)
* rlimit_core: rlim_t, # ditto
* rlimit_cpu: rlim_t, # ditto
* rlimit_data: rlim_t, # ditto
* rlimit_fsize: rlim_t, # ditto
* rlimit_memlock: rlim_t, # ditto
* rlimit_msgqueue: rlim_t, # ditto
* rlimit_nice: rlim_t, # ditto
* rlimit_nofile: rlim_t, # ditto
* rlimit_nproc: rlim_t, # ditto
* rlimit_rss: rlim_t, # ditto
* rlimit_rtprio: rlim_t, # ditto
* rlimit_rttime: rlim_t, # ditto
* rlimit_sbsize: rlim_t, # ditto
* rlimit_sigpending: rlim_t, # ditto
* rlimit_stack: rlim_t, # ditto
* uid: uid_t, # seteuid(2)
* umask: mode_t, # umask(2)
* unsetenv_others: boolx # Unset everything except the passed envp
* }
*
* # ====
*
* class Kernel
* def self?.exec
* : ( arg0 cmd, *argv args ) -> void
* | ( arg0 cmd, *argv args, argh opts) -> void
* | (envp env, arg0 cmd, *argv args ) -> void
* | (envp env, arg0 cmd, *argv args, argh opts) -> void
* end
* ```
*/
VALUE rb_f_exec(int argc, const VALUE *argv);
/**
* Waits for a process, with releasing GVL.
*
* @param[in] pid Process ID.
* @param[out] status The wait status is filled back.
* @param[in] flags Wait options.
* @retval -1 System call failed, errno set.
* @retval 0 WNOHANG but no waitable children.
* @retval otherwise A process ID that was `wait()`-ed.
* @post Upon successful return `status` is updated to have the process'
* status.
* @note `status` can be NULL.
* @note The arguments are passed through to underlying system call(s).
* Can have special meanings. For instance passing `(rb_pid_t)-1`
* to `pid` means it waits for any processes, under
* POSIX-compliant situations.
*/
rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags);
/**
* This is a shorthand of rb_waitpid without status and flags. It has been
* like this since the very beginning. The initial revision already did the
* same thing. Not sure why, then, it has been named `syswait`. AFAIK this is
* different from how `wait(3posix)` works.
*
* @param[in] pid Passed to rb_waitpid().
*/
void rb_syswait(rb_pid_t pid);
/**
* Identical to rb_f_exec(), except it spawns a child process instead of
* replacing the current one.
*
* @param[in] argc Number of objects in `argv`.
* @param[in] argv Command and its options to execute.
* @exception rb_eTypeError Invalid options e.g. non-String argv.
* @exception rb_eArgError Invalid options e.g. redirection cycle.
* @exception rb_eNotImpError Not implemented e.g. no `setuid(2)`.
* @exception rb_eRuntimeError `Process::UID.switch` in operation.
* @retval -1 Child process died for some reason.
* @retval otherwise The ID of the born child.
*
* @internal
*
* This is _really_ identical to rb_f_exec() until ultimately calling the
* system call. Almost everything are shared among these two (and
* rb_f_system()).
*/
rb_pid_t rb_spawn(int argc, const VALUE *argv);
/**
* Identical to rb_spawn(), except you can additionally know the detailed
* situation in case of abnormal parturitions.
*
* @param[in] argc Number of objects in `argv`.
* @param[in] argv Command and its options to execute.
* @param[out] errbuf Error description write-back buffer.
* @param[in] buflen Number of bytes of `errbuf`, including NUL.
* @exception rb_eTypeError Invalid options e.g. non-String argv.
* @exception rb_eArgError Invalid options e.g. redirection cycle.
* @exception rb_eNotImpError Not implemented e.g. no `setuid(2)`.
* @exception rb_eRuntimeError `Process::UID.switch` in operation.
* @retval -1 Child process died for some reason.
* @retval otherwise The ID of the born child.
* @post In case of `-1`, at most `buflen` bytes of the reason why is
* written back to `errbuf`.
*/
rb_pid_t rb_spawn_err(int argc, const VALUE *argv, char *errbuf, size_t buflen);
/**
* Gathers info about resources consumed by the current process.
*
* @param[in] _ Not used. Pass anything.
* @return An instance of `Process::Tms`.
*
* @internal
*
* This function might or might not exist depending on `./confiugre` result.
* It must be a portability hell. Better not use.
*/
VALUE rb_proc_times(VALUE _);
/**
* "Detaches" a subprocess. In POSIX systems every child processes that a
* process creates must be `wait(2)`-ed. A child process that died yet has not
* been waited so far is called a "zombie", which more or less consumes
* resources. This function automates reclamation of such processes. Once
* after this function successfully returns you can basically forget about the
* child process.
*
* @param[in] pid Process to wait.
* @return An instance of ::rb_cThread which is `waitpid(2)`-ing `pid`.
* @post You can just forget about the return value. GC reclaims it.
* @post You can know the exit status by querying `#value` of the
* return value (which is a blocking operation).
*/
VALUE rb_detach_process(rb_pid_t pid);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_PROCESS_H */
include/ruby/internal/intern/signal.h 0000644 00000015064 15040330603 0013711 0 ustar 00 #ifndef RBIMPL_INTERN_SIGNAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SIGNAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Signal handling APIs.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* signal.c */
RBIMPL_ATTR_NONNULL(())
/**
* Sends a signal ("kills") to processes.
*
* The first argument is the signal, either in:
*
* - Numerical representation (e.g. `9`), or
* - Textual representation of canonical (e.g. `:SIGKILL`) name or
* abbreviated (e.g. `:KILL`) name, either in ::rb_cSymbol or ::rb_cString.
*
* All the remaining arguments are numerical representations of process IDs.
* This function iterates over them to send the specified signal.
*
* You can specify both negative PIDs and negative signo to this function:
*
* ```
* sig \ pid | >= 1 | == 0 | == -1 | <= -2
* ===========+======+======+=======+=======
* > 0 | #1 | #2 | #3 | #4
* == 0 | #5 | #6 | #7 | #8
* < 0 | #9 | #10 | #11
* ```
*
* - Case #1: When signo and PID are both positive, this function sends the
* specified signal to the specified process (intuitive).
*
* - Case #2: When signo is positive and PID is zero, this function sends
* that signal to the current process group.
*
* - Case #3: When signo is positive and PID is -1, this function sends that
* signal to everything that the current process is allowed to kill.
*
* - Case #4: When signo is positive and PID is negative (but not -1), this
* function sends that signal to every processes in a process group, whose
* process group ID is the absolute value of the passed PID.
*
* - Case #5: When signo is zero and PID is positive, this function just
* checks for the existence of the specified process and doesn't send
* anything to anyone. In case the process is absent `Errno::ESRCH` is
* raised.
*
* - Case #6: When signo and PID are both zero, this function checks for the
* existence of the current process group. And it must do. This function
* is effectively a no-op then.
*
* - Case #7: When signo is zero and PID is -1, this function checks if there
* is any other process that the current process can kill. At least init
* (PID 1) must exist, so this must not fail.
*
* - Case #8: When signo is zero and PID is negative (but not -1), this
* function checks if there is a process group whose process group ID is
* the absolute value of the passed PID. In case the process group is
* absent `Errno::ESRCH` is raised.
*
* - Case #9: When signo is negative and PID is positive, this function sends
* the absolute value of the passed signo to the process group specified as
* the PID.
*
* - Case #10: When signo is negative and PID is zero, it is highly expected
* that this function sends the absolute value of the passed signo to the
* current process group. Strictly speaking, IEEE Std 1003.1-2017
* specifies that this (`killpg(3posix)` with an argument of zero) is an
* undefined behaviour. But no operating system is known so far that does
* things differently.
*
* - Case #11: When signo and PID are both negative, the behaviour of this
* function depends on how `killpg(3)` works. On Linux, it seems such
* attempt is strictly prohibited and `Errno::EINVAL` is raised. But on
* macOS, it seems it tries to to send the signal actually to the process
* group.
*
* @note Above description is in fact different from how `kill(2)` works.
* We interpret the passed arguments before passing them through to
* system calls.
* @param[in] argc Number of objects in `argv`.
* @param[in] argv Signal, followed by target PIDs.
* @exception rb_eArgError Unknown signal name.
* @exception rb_eSystemCallError Various errors sending signal to processes.
* @return Something numeric. The meaning of this return value is unclear.
* It seems in case of #1 above, this could be the body count. But
* other cases remain mysterious.
*/
VALUE rb_f_kill(int argc, const VALUE *argv);
/* This must be private, @shyouhei guesses. */
#ifdef POSIX_SIGNAL
#define posix_signal ruby_posix_signal
void (*posix_signal(int, void (*)(int)))(int);
#endif
RBIMPL_ATTR_PURE()
/**
* Queries the name of the signal. It returns for instance `"KILL"` for
* SIGKILL.
*
* @param[in] signo Signal number to query.
* @retval 0 No such signal.
* @retval otherwise A pointer to a static C string that is the name of
* the signal.
* @warning Don't free the return value.
*/
const char *ruby_signal_name(int signo);
/**
* Pretends as if there was no custom signal handler. This function sets the
* signal action to SIG_DFL, then kills itself.
*
* @param[in] sig The signal.
* @post Previous signal handler is lost.
* @post Passed signal is sent to the current process.
*
* @internal
*
* @shyouhei doesn't understand the needs of this function being visible from
* extension libraries.
*/
void ruby_default_signal(int sig);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_SIGNAL_H */
include/ruby/internal/intern/struct.h 0000644 00000020370 15040330603 0013754 0 ustar 00 #ifndef RBIMPL_INTERN_STRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_STRUCT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cStruct.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/intern/vm.h" /* rb_alloc_func_t */
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* struct.c */
/**
* Creates an instance of the given struct.
*
* @param[in] klass The class of the instance to allocate.
* @param[in] ... The fields.
* @return Allocated instance of `klass`.
* @pre `klass` must be a subclass of ::rb_cStruct.
* @note Number of variadic arguments must much that of the passed klass'
* fields.
*/
VALUE rb_struct_new(VALUE klass, ...);
/**
* Defines a struct class.
*
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
* an anonymous struct class then.
*
* @internal
*
* Not seriously checked but it seems this function does not share its
* implementation with how `Struct.new` is implemented...?
*/
VALUE rb_struct_define(const char *name, ...);
RBIMPL_ATTR_NONNULL((2))
/**
* Identical to rb_struct_define(), except it defines the class under the
* specified namespace instead of global toplevel.
*
* @param[out] space Namespace that the defining class shall reside.
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `name` is a constant under `space`.
* @note In contrast to rb_struct_define(), it doesn't make any sense to
* pass a null pointer to this function.
*/
VALUE rb_struct_define_under(VALUE space, const char *name, ...);
/**
* Identical to rb_struct_new(), except it takes the field values as a Ruby
* array.
*
* @param[in] klass The class of the instance to allocate.
* @param[in] values Field values.
* @return Allocated instance of `klass`.
* @pre `klass` must be a subclass of ::rb_cStruct.
* @pre `values` must be an instance of struct ::RArray.
*/
VALUE rb_struct_alloc(VALUE klass, VALUE values);
/**
* Mass-assigns a struct's fields.
*
* @param[out] self An instance of a struct class to squash.
* @param[in] values New values.
* @return ::RUBY_Qnil.
*/
VALUE rb_struct_initialize(VALUE self, VALUE values);
/**
* Identical to rb_struct_aref(), except it takes ::ID instead of ::VALUE.
*
* @param[in] self An instance of a struct class.
* @param[in] key Key to query.
* @exception rb_eTypeError `self` is not a struct.
* @exception rb_eNameError No such field.
* @return The value stored at `key` in `self`.
*/
VALUE rb_struct_getmember(VALUE self, ID key);
/**
* Queries the list of the names of the fields of the given struct class.
*
* @param[in] klass A subclass of ::rb_cStruct.
* @return The list of the names of the fields of `klass`.
*/
VALUE rb_struct_s_members(VALUE klass);
/**
* Queries the list of the names of the fields of the class of the given struct
* object. This is almost the same as calling rb_struct_s_members() over the
* class of the receiver.
*
* @internal
*
* "Almost"? What exactly is the difference?
*
* @endinternal
*
* @param[in] self An instance of a subclass of ::rb_cStruct.
* @return The list of the names of the fields.
*/
VALUE rb_struct_members(VALUE self);
/**
* Allocates an instance of the given class. This consequential name is of
* course because rb_struct_alloc() not only allocates but also initialises an
* instance. The API design is broken.
*
* @param[in] klass A subclass of ::rb_cStruct.
* @return An allocated instance of `klass`, not initialised.
*/
VALUE rb_struct_alloc_noinit(VALUE klass);
/**
* Identical to rb_struct_define(), except it does not define accessor methods.
* You have to define them yourself. Forget about the allocator function
* parameter; it is for internal use only. Extension libraries are unable to
* properly allocate a ruby struct, because `RStruct` is opaque.
*
* @internal
*
* Several flags must be set up properly for ::RUBY_T_STRUCT objects, which are
* also missing for extension libraries.
*
* @endinternal
*
* @param[in] name Name of the class.
* @param[in] super Superclass of the defining class.
* @param[in] func Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* zero. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
* an anonymous struct class then.
*/
VALUE rb_struct_define_without_accessor(const char *name, VALUE super, rb_alloc_func_t func, ...);
RBIMPL_ATTR_NONNULL((2))
/**
* Identical to rb_struct_define_without_accessor(), except it defines the
* class under the specified namespace instead of global toplevel. It can also
* be seen as a routine identical to rb_struct_define_under(), except it does
* not define accessor methods.
*
* @param[out] outer Namespace that the defining class shall reside.
* @param[in] class_name Name of the class.
* @param[in] super Superclass of the defining class.
* @param[in] alloc Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* zero. Each of which are the name of fields.
* @exception rb_eNameError `class_name` is not a constant name.
* @exception rb_eTypeError `class_name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `class_name` is a constant under `outer`.
* @note In contrast to rb_struct_define_without_accessor(), it doesn't
* make any sense to pass a null name.
*/
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_STRUCT_H */
include/ruby/internal/intern/object.h 0000644 00000046201 15040330603 0013677 0 ustar 00 #ifndef RBIMPL_INTERN_OBJECT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_OBJECT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cObject.
*/
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This macro is (used but) mysterious. Why on earth do we need this?
*
* - `obj != orig` check is done anyways inside of rb_obj_init_copy().
* - rb_obj_init_copy() returns something. No need are there to add `, 1`.
*/
#define RB_OBJ_INIT_COPY(obj, orig) \
((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
/** @old{RB_OBJ_INIT_COPY} */
#define OBJ_INIT_COPY(obj, orig) RB_OBJ_INIT_COPY(obj, orig)
/* object.c */
/**
* Identical to rb_class_new_instance(), except it passes the passed keywords
* if any to the `#initialize` method.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] klass An instance of ::rb_cClass.
* @exception rb_eTypeError `klass`'s allocator is undefined.
* @exception rb_eException Any exceptions can happen inside.
* @return An allocated new instance of `klass`.
* @note This is _the_ implementation of `Object.new`.
*/
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass);
/**
* Allocates, then initialises an instance of the given class. It first calls
* the passed class' allocator to obtain an uninitialised object, then calls
* its initialiser with the remaining arguments.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to `#initialize`.
* @param[in] klass An instance of ::rb_cClass.
* @exception rb_eTypeError `klass`'s allocator is undefined.
* @exception rb_eException Any exceptions can happen inside.
* @return An allocated new instance of `klass`.
*/
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass);
/**
* Identical to rb_class_new_instance(), except you can specify how to handle
* the last element of the given array.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] klass An instance of ::rb_cClass.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eTypeError `klass`'s allocator is undefined.
* @exception rb_eException Any exceptions can happen inside.
* @return An allocated new instance of `klass`.
*/
VALUE rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_splat);
/**
* Checks for equality of the passed objects, in terms of `Object#eql?`.
*
* @param[in] lhs Comparison left hand side.
* @param[in] rhs Comparison right hand side.
* @retval non-zero They are equal.
* @retval 0 Otherwise.
* @note This function actually calls `lhs.eql?(rhs)` so you cannot
* implement your class' `#eql?` method using it.
*/
int rb_eql(VALUE lhs, VALUE rhs);
/**
* Generates a textual representation of the given object.
*
* @param[in] obj Arbitrary ruby object.
* @return An instance of ::rb_cString that represents `obj`.
* @note This is the default implementation of `Object#to_s` that each
* subclasses want to override.
*/
VALUE rb_any_to_s(VALUE obj);
/**
* Generates a human-readable textual representation of the given object. This
* is largely similar to Ruby level `Object#inspect` but not the same; it
* additionally escapes the inspection result so that the string be compatible
* with that of default internal (or default external, if absent).
*
* @param[in] obj Arbitrary ruby object.
* @return An instance of ::rb_cString that represents `obj`.
*/
VALUE rb_inspect(VALUE obj);
/**
* Queries if the given object is a direct instance of the given class.
*
* @param[in] obj Arbitrary ruby object.
* @param[in] klass An instance of ::rb_cModule.
* @exception rb_eTypeError `klass` is neither module nor class.
* @retval RUBY_Qtrue `obj` is an instance of `klass`.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_obj_is_instance_of(VALUE obj, VALUE klass);
/**
* Queries if the given object is an instance (of possibly descendants) of the
* given class.
*
* @param[in] obj Arbitrary ruby object.
* @param[in] klass An instance of ::rb_cModule.
* @exception rb_eTypeError `klass` is neither module nor class.
* @retval RUBY_Qtrue `obj` is a `klass`.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);
/**
* Allocates an instance of the given class.
*
* @param[in] klass A class to instantiate.
* @exception rb_eTypeError `klass` is not a class.
* @return An allocated, not yet initialised instance of `klass`.
* @note It calls the allocator defined by rb_define_alloc_func(). You
* cannot use this function to define an allocator. Use
* rb_newobj_of(), #TypedData_Make_Struct or others, instead.
* @note Usually prefer rb_class_new_instance() to rb_obj_alloc() and
* rb_obj_call_init().
* @see rb_class_new_instance()
* @see rb_obj_call_init()
* @see rb_define_alloc_func()
* @see rb_newobj_of()
* @see #TypedData_Make_Struct
*/
VALUE rb_obj_alloc(VALUE klass);
/**
* Produces a shallow copy of the given object. Its list of instance variables
* are copied, but not the objects they reference. It also copies the frozen
* value state.
*
* @param[in] obj Arbitrary ruby object.
* @exception rb_eException `#initialize_copy` can raise anything.
* @return A "clone" of `obj`.
*
* @internal
*
* Unlike ruby-level `Object#clone`, there is no way to control the frozen-ness
* of the return value.
*/
VALUE rb_obj_clone(VALUE obj);
/**
* Duplicates the given object. This does almost the same thing as
* rb_obj_clone() do. However it does not copy the singleton class (if any).
* It also doesn't copy frozen-ness.
*
* @param[in] obj Arbitrary ruby object.
* @exception rb_eException `#initialize_copy` can raise anything.
* @return A shallow copy of `obj`.
*/
VALUE rb_obj_dup(VALUE obj);
/**
* Default implementation of `#initialize_copy`, `#initialize_dup` and
* `#initialize_clone`. It does almost nothing. Just raises exceptions for
* checks.
*
* @param[in] dst The destination object.
* @param[in] src The source object.
* @exception rb_eFrozenError `dst` is frozen.
* @exception rb_eTypeError `dst` and `src` have different classes.
* @return Always returns `dst`.
*/
VALUE rb_obj_init_copy(VALUE src, VALUE dst);
/**
* Just calls rb_obj_freeze_inline() inside. Does this make any sens to
* extension libraries?
*
* @param[out] obj Object to freeze.
* @return Verbatim `obj`.
*/
VALUE rb_obj_freeze(VALUE obj);
RBIMPL_ATTR_PURE()
/**
* Just calls RB_OBJ_FROZEN() inside. Does this make any sens to extension
* libraries?
*
* @param[in] obj Object in question.
* @retval RUBY_Qtrue Yes it is.
* @retval RUBY_Qfalse No it isn't.
*/
VALUE rb_obj_frozen_p(VALUE obj);
/* gc.c */
/**
* Finds or creates an integer primary key of the given object. In the old
* days this function was a purely arithmetic operation that maps the
* underlying memory address where the object resides into a Ruby's integer.
* Some time around 2.x this changed. It no longer relates its return values
* to C level pointers. This function assigns some random number to the given
* object if absent. The same number will be returned on all subsequent
* requests. No two active objects share a number.
*
* @param[in] obj Arbitrary ruby object.
* @return An instance of ::rb_cInteger which is an "identifier" of `obj`.
*
* @internal
*
* The "some random number" is in fact a monotonic-increasing process-global
* unique integer, much like an `INTEGER AUTO_INCREMENT PRIMARY KEY` column in
* a MySQL table.
*/
VALUE rb_obj_id(VALUE obj);
RBIMPL_ATTR_CONST()
/**
* Identical to rb_obj_id(), except it hesitates from allocating a new instance
* of ::rb_cInteger. rb_obj_id() could allocate ::RUBY_T_BIGNUM objects. That
* allocation might perhaps impact negatively. On such situations, this
* function instead returns one-shot temporary small integers that need no
* allocations at all. The values are guaranteed unique at the moment, but no
* future promise is made; could be reused. Use of this API should be very
* instant. It is a failure to store the returned integer to somewhere else.
*
* In short it is difficult to use.
*
* @param[in] obj Arbitrary ruby object.
* @return An instance of ::rb_cInteger unique at the moment.
*
* @internal
*
* This is roughly the old behaviour of rb_obj_id().
*/
VALUE rb_memory_id(VALUE obj);
/* object.c */
RBIMPL_ATTR_PURE()
/**
* Finds a "real" class. As the name implies there are class objects that are
* surreal. This function takes a class, traverses its ancestry tree, and
* returns its nearest ancestor which is neither a module nor a singleton
* class.
*
* @param[in] klass An instance of ::rb_cClass.
* @retval RUBY_Qfalse No real class in `klass`' ancestry tree.
* @retval klass `klass` itself is a real class.
* @retval otherwise Nearest ancestor of `klass` who is real.
*/
VALUE rb_class_real(VALUE klass);
RBIMPL_ATTR_PURE()
/**
* Determines if the given two modules are relatives.
*
* @param[in] scion Possible subclass.
* @param[in] ascendant Possible superclass.
* @exception rb_eTypeError `ascendant` is not a module.
* @retval RUBY_Qtrue `scion` inherits, or is equal to `ascendant`.
* @retval RUBY_Qfalse `ascendant` inherits `scion`.
* @retval RUBY_Qnil They are not relatives.
*/
VALUE rb_class_inherited_p(VALUE scion, VALUE ascendant);
RBIMPL_ATTR_PURE()
/**
* Queries the parent of the given class.
*
* @param[in] klass A child class.
* @exception rb_eTypeError `klass` is a `Class.allocate`.
* @retval RUBY_Qfalse `klass` has no superclass.
* @retval otherwise `klass`' superclass.
*
* @internal
*
* Is there any class except ::rb_cBasicObject, that has no superclass?
*/
VALUE rb_class_superclass(VALUE klass);
RBIMPL_ATTR_NONNULL(())
/**
* Converts an object into another type. Calls the specified conversion method
* if necessary.
*
* @param[in] val An object to convert.
* @param[in] type A value of enum ::ruby_value_type.
* @param[in] name Name to display on error (e.g. "Array").
* @param[in] mid Conversion method (e.g. "to_ary").
* @exception rb_eTypeError Failed to convert.
* @return An object of the specified type.
*/
VALUE rb_convert_type(VALUE val, int type, const char *name, const char *mid);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_convert_type(), except it returns ::RUBY_Qnil instead of
* raising exceptions, in case of conversion failure. It still raises
* exceptions for various reasons, like when the conversion method itself
* raises, though.
*
* @param[in] val An object to convert.
* @param[in] type A value of enum ::ruby_value_type.
* @param[in] name Name to display on error (e.g. "Array").
* @param[in] mid Conversion method (e.g. "to_ary").
* @exception rb_eTypeError The `mid` does not generate `type`.
* @retval RUBY_Qnil No conversion defined.
* @retval otherwise An object of the specified type.
*/
VALUE rb_check_convert_type(VALUE val, int type, const char *name, const char *mid);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_check_convert_type(), except the return value type is fixed
* to ::rb_cInteger.
*
* @param[in] val An object to convert.
* @param[in] mid Conversion method (e.g. "to_ary").
* @exception rb_eTypeError The `mid` does not generate an integer.
* @retval RUBY_Qnil No conversion defined.
* @retval otherwise An instance of ::rb_cInteger.
*/
VALUE rb_check_to_integer(VALUE val, const char *mid);
/**
* This is complicated.
*
* - When the passed object is already an instance of ::rb_cFloat, just
* returns it as-is.
*
* - When the passed object is something numeric, the function tries to
* convert it using `#to_f` method.
*
* - If that conversion fails (this happens for instance when the numeric
* is a complex) it returns ::RUBY_Qnil.
*
* - Otherwise returns the conversion result.
*
* - Otherwise it also returns ::RUBY_Qnil.
*
* @param[in] val An object to convert.
* @retval RUBY_Qnil Conversion from `val` to float is undefined.
* @retval otherwise Converted result.
*/
VALUE rb_check_to_float(VALUE val);
/**
* Identical to rb_check_to_int(), except it raises in case of conversion
* mismatch.
*
* @param[in] val An object to convert.
* @exception rb_eTypeError `#to_int` does not generate an integer.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_to_int(VALUE val);
/**
* Identical to rb_check_to_integer(), except it uses `#to_int` for conversion.
*
* @param[in] val An object to convert.
* @exception rb_eTypeError `#to_int` does not return an integer.
* @retval RUBY_Qnil No conversion defined.
* @retval otherwise An instance of ::rb_cInteger.
*/
VALUE rb_check_to_int(VALUE val);
/**
* This is the logic behind `Kernel#Integer`. Numeric types are converted
* directly, with floating point numbers being truncated. Strings are
* interpreted strictly; only leading/trailing whitespaces, plus/minus sign,
* radix indicators such as `0x`, digits, and underscores are allowed.
* Anything else are converted by first trying `#to_int`, then `#to_i`.
*
* This is slightly stricter than `String#to_i`.
*
* @param[in] val An object to convert.
* @exception rb_eArgError Malformed `val` passed.
* @exception rb_eTypeError No conversion defined.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_Integer(VALUE val);
/**
* Identical to rb_check_to_float(), except it raises on error.
*
* @param[in] val An object to convert.
* @exception rb_eTypeError No conversion defined.
* @return An instance of ::rb_cFloat.
*/
VALUE rb_to_float(VALUE val);
/**
* This is the logic behind `Kernel#Float`. Numeric types are converted
* directly to the nearest value that a Float can represent. Strings are
* interpreted strictly; only leading/trailing whitespaces are allowed except
* what `strtod` understands. Anything else are converted using `#to_f`.
*
* This is slightly stricter than `String#to_f`.
*
* @param[in] val An object to convert.
* @exception rb_eArgError Malformed `val` passed.
* @exception rb_eTypeError No conversion defined.
* @return An instance of ::rb_cFloat.
*/
VALUE rb_Float(VALUE val);
/**
* This is the logic behind `Kernel#String`. Arguments are converted by first
* trying `#to_str`, then `#to_s`.
*
* @param[in] val An object to convert.
* @exception rb_eTypeError No conversion defined.
* @return An instance of ::rb_cString.
*/
VALUE rb_String(VALUE val);
/**
* This is the logic behind `Kernel#Array`. Arguments are converted by first
* trying `#to_ary`, then `#to_a`, and if both failed, returns an array of
* length 1 that contains the passed argument as the sole contents.
*
* @param[in] val An object to convert.
* @return An instance of ::rb_cArray.
*/
VALUE rb_Array(VALUE val);
/**
* This is the logic behind `Kernel#Hash`. Arguments are converted by first
* trying `#to_hash`. if it failed, and the argument is either ::RUBY_Qnil or
* an empty array, returns an empty hash. Otherwise an exception is raised.
*
* @param[in] val An object to convert.
* @exception rb_eTypeError No conversion defined.
* @return An instance of ::rb_cHash.
*/
VALUE rb_Hash(VALUE val);
RBIMPL_ATTR_NONNULL(())
/**
* Converts a textual representation of a real number into a numeric, which is
* the nearest value that the return type can represent, of the value that the
* argument represents. This is in fact a 2-in-1 function whose behaviour can
* be controlled using the second (mode) argument. If the mode is zero, this
* function is in "historical" mode which only understands "floating-constant"
* defined at ISO/IEC 9899:1990 section 6.1.3.1. If the mode is nonzero, it is
* in "extended" mode, which also accepts "hexadecimal-floating-constant"
* defined at ISO/IEC 9899:2018 section 6.4.4.2.
*
* @param[in] str A textual representation of a real number.
* @param[in] mode Conversion mode, as described above.
* @exception rb_eArgError Malformed `str` passed.
* @see https://bugs.ruby-lang.org/issues/2969
* @note Null pointers are allowed, and it returns 0.0 then.
*/
double rb_cstr_to_dbl(const char *str, int mode);
/**
* Identical to rb_cstr_to_dbl(), except it accepts a Ruby's string instead of
* C's.
*
* @param[in] str A textual representation of a real number.
* @param[in] mode Conversion mode, as described in rb_cstr_to_dbl().
* @exception rb_eArgError Malformed `str` passed.
* @see https://bugs.ruby-lang.org/issues/2969
*/
double rb_str_to_dbl(VALUE str, int mode);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_OBJECT_H */
include/ruby/internal/intern/class.h 0000644 00000037263 15040330603 0013546 0 ustar 00 #ifndef RBIMPL_INTERN_CLASS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_CLASS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cClass/::rb_cModule.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* class.c */
/**
* Creates a new, anonymous class.
*
* @param[in] super What would become a parent class.
* @exception rb_eTypeError `super` is not something inheritable.
* @return An anonymous class that inherits `super`.
*/
VALUE rb_class_new(VALUE super);
/**
* The comment that comes with this function says `:nodoc:`. Not sure what
* that means though.
*
* @param[out] clone Destination object.
* @param[in] orig Source object.
* @exception rb_eTypeError Cannot copy `orig`.
* @return The passed `clone`.
*/
VALUE rb_mod_init_copy(VALUE clone, VALUE orig);
/**
* Asserts that the given class can derive a child class. A class might or
* might not be able to do so; for instance a singleton class cannot.
*
* @param[in] super Possible super class.
* @exception rb_eTypeError No it cannot.
* @post Upon successful return `super` can derive.
*/
void rb_check_inheritable(VALUE super);
/**
* This is a very badly designed API that creates an anonymous class.
*
* @param[in] id Discarded for no reason (why...).
* @param[in] super What would become a parent class. 0 means
* ::rb_cObject.
* @exception rb_eTypeError `super` is not something inheritable.
* @return An anonymous class that inherits `super`.
* @warning You must explicitly name the return value.
*/
VALUE rb_define_class_id(ID id, VALUE super);
/**
* Identical to rb_define_class_under(), except it takes the name in ::ID
* instead of C's string.
*
* @param[out] outer A class which contains the new class.
* @param[in] id Name of the new class
* @param[in] super A class from which the new class will derive.
* 0 means ::rb_cObject.
* @exception rb_eTypeError The constant name `id` is already taken but the
* constant is not a class.
* @exception rb_eTypeError The class is already defined but the class can
* not be reopened because its superclass is not
* `super`.
* @exception rb_eArgError `super` is NULL.
* @return The created class.
* @post `outer::id` refers the returned class.
* @note If a class named `id` is already defined and its superclass is
* `super`, the function just returns the defined class.
* @note The compaction GC does not move classes returned by this
* function.
*/
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super);
/**
* Creates a new, anonymous module.
*
* @return An anonymous module.
*/
VALUE rb_module_new(void);
/**
* Creates a new, anonymous refinement.
*
* @return An anonymous refinement.
*/
VALUE rb_refinement_new(void);
/**
* This is a very badly designed API that creates an anonymous module.
*
* @param[in] id Discarded for no reason (why...).
* @return An anonymous module.
* @warning You must explicitly name the return value.
*/
VALUE rb_define_module_id(ID id);
/**
* Identical to rb_define_module_under(), except it takes the name in ::ID
* instead of C's string.
*
* @param[out] outer A class which contains the new module.
* @param[in] id Name of the new module
* @exception rb_eTypeError The constant name `id` is already taken but the
* constant is not a module.
* @return The created module.
* @post `outer::id` refers the returned module.
* @note The compaction GC does not move classes returned by this
* function.
*/
VALUE rb_define_module_id_under(VALUE outer, ID id);
/**
* Queries the list of included modules. It can also be seen as a routine to
* first call rb_mod_ancestors(), then rejects non-modules from the return
* value.
*
* @param[in] mod Class or Module.
* @return An array of modules that are either included or prepended in any
* of `mod`'s ancestry tree (including itself).
*/
VALUE rb_mod_included_modules(VALUE mod);
/**
* Queries if the passed module is included by the module. It can also be seen
* as a routine to first call rb_mod_included_modules(), then see if the return
* value contains the passed module.
*
* @param[in] child A Module.
* @param[in] parent Another Module.
* @exception rb_eTypeError `child` is not an instance of ::rb_cModule.
* @retval RUBY_Qtrue `parent` is either included or prepended in any
* of `child`'s ancestry tree (including itself).
* @return RUBY_Qfalse Otherwise.
*/
VALUE rb_mod_include_p(VALUE child, VALUE parent);
/**
* Queries the module's ancestors. This routine gathers classes and modules
* that the passed module either inherits, includes, or prepends, then
* recursively applies that routine again and again to the collected entries
* until the list doesn't grow up.
*
* @param[in] mod A module or a class.
* @return An array of classes or modules that `mod` possibly recursively
* inherits, includes, or prepends.
*
* @internal
*
* Above description is written in a recursive language but in practice it
* computes the return value iteratively.
*/
VALUE rb_mod_ancestors(VALUE mod);
/**
* Queries the class's descendants. This routine gathers classes that are
* subclasses of the given class (or subclasses of those subclasses, etc.),
* returning an array of classes that have the given class as an ancestor.
* The returned array does not include the given class or singleton classes.
*
* @param[in] klass A class.
* @return An array of classes where `klass` is an ancestor.
*
* @internal
*/
VALUE rb_class_descendants(VALUE klass);
/**
* Queries the class's direct descendants. This routine gathers classes that are
* direct subclasses of the given class,
* returning an array of classes that have the given class as a superclass.
* The returned array does not include singleton classes.
*
* @param[in] klass A class.
* @return An array of classes where `klass` is the `superclass`.
*
* @internal
*/
VALUE rb_class_subclasses(VALUE klass);
/**
* Returns the attached object for a singleton class.
* If the given class is not a singleton class, raises a TypeError.
*
* @param[in] klass A class.
* @return The object which has the singleton class `klass`.
*
* @internal
*/
VALUE rb_class_attached_object(VALUE klass);
/**
* Generates an array of symbols, which are the list of method names defined in
* the passed class.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Array of at most one object, which controls (if
* any) whether the return array includes the names
* of methods defined in ancestors or not.
* @param[in] mod A module or a class.
* @exception rb_eArgError `argc` out of range.
* @return An array of symbols collecting names of instance methods that
* are not private, defined at `mod`.
*/
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_class_instance_methods(), except it returns names of methods
* that are public only.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Array of at most one object, which controls (if
* any) whether the return array includes the names
* of methods defined in ancestors or not.
* @param[in] mod A module or a class.
* @exception rb_eArgError `argc` out of range.
* @return An array of symbols collecting names of instance methods that
* are public, defined at `mod`.
*/
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_class_instance_methods(), except it returns names of methods
* that are protected only.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Array of at most one object, which controls (if
* any) whether the return array includes the names
* of methods defined in ancestors or not.
* @param[in] mod A module or a class.
* @exception rb_eArgError `argc` out of range.
* @return An array of symbols collecting names of instance methods that
* are protected, defined at `mod`.
*/
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_class_instance_methods(), except it returns names of methods
* that are private only.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Array of at most one object, which controls (if
* any) whether the return array includes the names
* of methods defined in ancestors or not.
* @param[in] mod A module or a class.
* @exception rb_eArgError `argc` out of range.
* @return An array of symbols collecting names of instance methods that
* are protected, defined at `mod`.
*/
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_class_instance_methods(), except it returns names of
* singleton methods instead of instance methods.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Array of at most one object, which controls (if
* any) whether the return array includes the names
* of methods defined in ancestors or not.
* @param[in] obj Arbitrary ruby object.
* @exception rb_eArgError `argc` out of range.
* @return An array of symbols collecting names of instance methods that
* are not private, defined at the singleton class of `obj`.
*/
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj);
/**
* Identical to rb_define_method(), except it takes the name of the method in
* ::ID instead of C's string.
*
* @param[out] klass A module or a class.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_method_id
*/
void rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int arity);
/* vm_method.c */
/**
* Inserts a method entry that hides previous method definition of the given
* name. This is not a deletion of a method. Method of the same name defined
* in a parent class is kept invisible in this way.
*
* @param[out] mod The module to insert an undef.
* @param[in] mid Name of the undef.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method named `klass#name`.
* @post `klass#name` is undefined.
* @see rb_undef_method
*
* @internal
*
* @shyouhei doesn't understand why this is not the ::ID -taking variant of
* rb_undef_method(), given rb_remove_method() has its ::ID -taking counterpart
* named rb_remove_method_id().
*/
void rb_undef(VALUE mod, ID mid);
/* class.c */
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_define_method(), except it defines a protected method.
*
* @param[out] klass A module or a class.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method
*/
void rb_define_protected_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_define_method(), except it defines a private method.
*
* @param[out] klass A module or a class.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method
*/
void rb_define_private_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_define_method(), except it defines a singleton method.
*
* @param[out] obj Arbitrary ruby object.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_singleton_method
*/
void rb_define_singleton_method(VALUE obj, const char *mid, VALUE(*func)(ANYARGS), int arity);
/**
* Finds or creates the singleton class of the passed object.
*
* @param[out] obj Arbitrary ruby object.
* @exception rb_eTypeError `obj` cannot have its singleton class.
* @return A (possibly newly allocated) instance of ::rb_cClass.
* @post `obj` has its singleton class, which is the return value.
* @post In case `obj` is a class, the returned singleton class also has
* its own singleton class in order to keep consistency of the
* inheritance structure of metaclasses.
* @note A new singleton class will be created if `obj` did not have
* one.
* @note The singleton classes for ::RUBY_Qnil, ::RUBY_Qtrue, and
* ::RUBY_Qfalse are ::rb_cNilClass, ::rb_cTrueClass, and
* ::rb_cFalseClass respectively.
*
* @internal
*
* You can _create_ a singleton class of a frozen object. Intentional or ...?
*
* Nowadays there are wider range of objects who cannot have singleton classes
* than before. For instance some string instances cannot for some reason.
*/
VALUE rb_singleton_class(VALUE obj);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_CLASS_H */
include/ruby/internal/intern/select.h 0000644 00000007552 15040330603 0013716 0 ustar 00 #ifndef RBIMPL_INTERN_SELECT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs to provide ::rb_fd_select().
* @note Functions and structs defined in this header file are not
* necessarily ruby-specific. They don't need ::VALUE etc.
*/
#include "ruby/internal/config.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* for NFDBITS (BSD Net/2) */
#endif
#include "ruby/internal/dllexport.h"
/* thread.c */
#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
# include "ruby/internal/intern/select/largesize.h"
#elif defined(_WIN32)
# include "ruby/internal/intern/select/win32.h"
# /** Does nothing (defined for compatibility). */
# define rb_fd_resize(n, f) ((void)(f))
#else
# include "ruby/internal/intern/select/posix.h"
# /** Does nothing (defined for compatibility). */
# define rb_fd_resize(n, f) ((void)(f))
#endif
RBIMPL_SYMBOL_EXPORT_BEGIN()
struct timeval;
/**
* Waits for multiple file descriptors at once. This is basically a wrapper of
* system-provided select() with releasing GVL, to allow other Ruby threads run
* in parallel.
*
* @param[in] nfds Max FD in everything passed, plus one.
* @param[in,out] rfds Set of FDs to wait for reads.
* @param[in,out] wfds Set of FDs to wait for writes.
* @param[in,out] efds Set of FDs to wait for OOBs.
* @param[in,out] timeout Max blocking duration.
* @retval -1 Failed, errno set.
* @retval 0 Timeout exceeded.
* @retval otherwise Total number of file descriptors returned.
* @post `rfds` contains readable FDs.
* @post `wfds` contains writable FDs.
* @post `efds` contains exceptional FDs.
* @post `timeout` is the time left.
* @note All pointers are allowed to be null pointers.
*
* Although backend threads can run in parallel of this function, touching a
* file descriptor from multiple threads could be problematic. For instance
* what happens when a thread closes a file descriptor that is selected by
* someone else, vastly varies among operating systems. You would better avoid
* touching an fd from more than one threads.
*
* @internal
*
* Although any file descriptors are possible here, it makes completely no
* sense to pass a descriptor that is not `O_NONBLOCK`. If you want to know
* the reason for this limitatuon in detail, you might find this thread super
* interesting: https://lkml.org/lkml/2004/10/6/117
*/
int rb_thread_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_SELECT_H */
include/ruby/internal/intern/ruby.h 0000644 00000005440 15040330603 0013412 0 ustar 00 #ifndef RBIMPL_INTERN_RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RUBY_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Process-global APIs.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* ruby.c */
/** @alias{rb_get_argv} */
#define rb_argv rb_get_argv()
/**
* The value of `$0` at process bootup.
*
* @note This is just a snapshot of `$0`, not the backend storage of it. `$0`
* could become something different because it is a writable global
* variable. Modifying it for instance affects `ps(1)` output. Don't
* assume they are synced.
*/
RUBY_EXTERN VALUE rb_argv0;
/* io.c */
/**
* Queries the arguments passed to the current process that you can access from
* Ruby as `ARGV`.
*
* @return An array of strings containing arguments passed to the process.
*/
VALUE rb_get_argv(void);
/* ruby.c */
RBIMPL_ATTR_NONNULL(())
/**
* Loads the given file. This function opens the given pathname for reading,
* parses the contents as a Ruby script, and returns an opaque "node" pointer.
* You can then pass it to ruby_run_node() for evaluation.
*
* @param[in] file File name, or "-" to read from stdin.
* @return Opaque "node" pointer.
*/
void *rb_load_file(const char *file);
/**
* Identical to rb_load_file(), except it takes the argument as a Ruby's string
* instead of C's.
*
* @param[in] file File name, or "-" to read from stdin.
* @return Opaque "node" pointer.
*/
void *rb_load_file_str(VALUE file);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RUBY_H */
include/ruby/internal/intern/random.h 0000644 00000010460 15040330603 0013707 0 ustar 00 #ifndef RBIMPL_INTERN_RANDOM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RANDOM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief MT19937 backended pseudo random number generator.
* @see Matsumoto, M., Nishimura, T., "Mersenne Twister: A 623-
* dimensionally equidistributed uniform pseudorandom number
* generator", ACM Trans. on Modeling and Computer Simulation, 8
* (1): pp 3-30, 1998. https://doi.org/10.1145/272991.272995
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* random.c */
/**
* Generates a 32 bit random number.
*
* @return A random number.
* @note Now that we have ractors, the RNG behind this function is
* per-ractor.
*/
unsigned int rb_genrand_int32(void);
/**
* Generates a `double` random number.
*
* @return A random number.
* @note This function shares the RNG with rb_genrand_int32().
*/
double rb_genrand_real(void);
/**
* Resets the RNG behind rb_genrand_int32()/rb_genrand_real().
*
* @post The (now per-ractor) default RNG's internal state is cleared.
*/
void rb_reset_random_seed(void);
/**
* Generates a String of random bytes.
*
* @param[in,out] rnd An instance of ::rb_cRandom.
* @param[in] n Requested number of bytes.
* @return An instance of ::rb_cString, of binary, of `n` bytes length,
* whose contents are random bits.
*
* @internal
*
* @shyouhei doesn't know if this is an Easter egg or an official feature, but
* this function can take a wider range of objects, such as `Socket::Ifaddr`.
* The arguments are just silently ignored and the default RNG is used instead,
* if they are non-RNG.
*/
VALUE rb_random_bytes(VALUE rnd, long n);
/**
* Identical to rb_genrand_int32(), except it generates using the passed RNG.
*
* @param[in,out] rnd An instance of ::rb_cRandom.
* @return A random number.
*/
unsigned int rb_random_int32(VALUE rnd);
/**
* Identical to rb_genrand_real(), except it generates using the passed RNG.
*
* @param[in,out] rnd An instance of ::rb_cRandom.
* @return A random number.
*/
double rb_random_real(VALUE rnd);
/**
* Identical to rb_genrand_ulong_limited(), except it generates using the
* passed RNG.
*
* @param[in,out] rnd An instance of ::rb_cRandom.
* @param[in] limit Max possible return value.
* @return A random number, distributed in `[0, limit]` interval.
* @note Note it can return `limit`.
* @note Whether the return value distributes uniformly in the
* interval or not depends on how the argument RNG behaves; at
* least in case of MT19937 it does.
*/
unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit);
/**
* Generates a random number whose upper limit is `i`.
*
* @param[in] i Max possible return value.
* @return A random number, uniformly distributed in `[0, limit]` interval.
* @note Note it can return `i`.
*/
unsigned long rb_genrand_ulong_limited(unsigned long i);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RANDOM_H */
include/ruby/internal/intern/variable.h 0000644 00000051474 15040330603 0014226 0 ustar 00 #ifndef RBIMPL_INTERN_VARIABLE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_VARIABLE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to names inside of a Ruby program.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/st.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* variable.c */
/**
* Queries the name of a module.
*
* @param[in] mod An instance of ::rb_cModule.
* @retval RUBY_Qnil `mod` is anonymous.
* @retval otherwise `mod` is onymous.
*/
VALUE rb_mod_name(VALUE mod);
/**
* Identical to rb_mod_name(), except it returns `#<Class: ...>` style
* inspection for anonymous modules.
*
* @param[in] mod An instance of ::rb_cModule.
* @return An instance of ::rb_cString representing `mod`'s path.
*/
VALUE rb_class_path(VALUE mod);
/**
* @alias{rb_mod_name}
*
* @internal
*
* Am I missing something? Why we have the same thing in different names?
*/
VALUE rb_class_path_cached(VALUE mod);
RBIMPL_ATTR_NONNULL(())
/**
* Names a class.
*
* @param[out] klass Target module to name.
* @param[out] space Namespace that `klass` shall reside.
* @param[in] name Name of `klass`.
* @post `klass` has `space::klass` name.
*/
void rb_set_class_path(VALUE klass, VALUE space, const char *name);
/**
* Identical to rb_set_class_path(), except it accepts the name as Ruby's
* string instead of C's.
*
* @param[out] klass Target module to name.
* @param[out] space Namespace that `klass` shall reside.
* @param[in] name Name of `klass`.
* @post `klass` has `space::klass` name.
*/
void rb_set_class_path_string(VALUE klass, VALUE space, VALUE name);
/**
* Identical to rb_path2class(), except it accepts the path as Ruby's string
* instead of C's.
*
* @param[in] path Path to query.
* @exception rb_eArgError No such constant.
* @exception rb_eTypeError The path resolved to a non-module.
* @return Resolved class.
*/
VALUE rb_path_to_class(VALUE path);
RBIMPL_ATTR_NONNULL(())
/**
* Resolves a `Q::W::E::R`-style path string to the actual class it points.
*
* @param[in] path Path to query.
* @exception rb_eArgError No such constant.
* @exception rb_eTypeError The path resolved to a non-module.
* @return Resolved class.
*/
VALUE rb_path2class(const char *path);
/**
* Queries the name of the given object's class.
*
* @param[in] obj Arbitrary object.
* @return An instance of ::rb_cString representing `obj`'s class' path.
*/
VALUE rb_class_name(VALUE obj);
/**
* Kicks the autoload procedure as if it was "touched".
*
* @param[out] space Namespace where autoload is defined.
* @param[in] name Name of the autoloaded constant.
* @retval RUBY_Qfalse No such autoload.
* @retval RUBY_Qtrue Autoload successfully initiated.
* @note As an autoloaded library is expected to define `space::name`,
* it is a nature of this function to have process-global side
* effects.
* @note Multiple threads can simultaneously call this API. It blocks
* then. That must not last indefinitely but can take longer than
* you expect.
*
* @internal
*
* @shyouhei has no idea why extension libraries should use this API.
*/
VALUE rb_autoload_load(VALUE space, ID name);
/**
* Queries if an autoload is defined at a point.
*
* @param[in] space Namespace where autoload is defined.
* @param[in] name Name of the autoloaded constant.
* @retval RUBY_Qnil No such autoload.
* @retval otherwise The feature (path) registered at `space::name`.
*/
VALUE rb_autoload_p(VALUE space, ID name);
/**
* Traces a global variable.
*
* @param[in] argc Either 1 or 2.
* @param[in] argv Variable name, optionally a Proc.
* @retval RUBY_Qnil No previous tracers.
* @retval otherwise Previous tracers.
*
* @internal
*
* @shyouhei has no idea why extension libraries should use this API.
*/
VALUE rb_f_trace_var(int argc, const VALUE *argv);
/**
* Deletes the passed tracer from the passed global variable, or if omitted,
* deletes everything.
*
* @param[in] argc Either 1 or 2.
* @param[in] argv Variable name, optionally a Proc.
* @retval RUBY_Qnil No previous tracers.
* @retval otherwise Deleted tracers.
*
* @internal
*
* @shyouhei has no idea why extension libraries should use this API.
*/
VALUE rb_f_untrace_var(int argc, const VALUE *argv);
/**
* Queries the list of global variables.
*
* @return The list of the name of the global variables.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_f_global_variables(void);
/**
* Aliases a global variable. Did you know that you can alias a global
* variable? It is like aliasing methods:
*
* ```ruby
* alias $dst $src
* ```
*
* This C function does the same thing.
*
* @param[in] dst Destination name.
* @param[in] src Source name.
* @post A global variable named `dst` is defined to be an alias of a
* global variable named `src`.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_alias_variable(ID dst, ID src);
/**
* Frees the list of instance variables. 3rd parties need not know, but there
* are several ways to store an object's instance variables, depending on its
* internal structure. This function makes sense when the passed objects is
* using so-called "generic" backend storage. People need not be aware of this
* working behind-the-scenes.
*
* @param[out] obj The object in question.
*
* @internal
*
* This just destroys the given object. @shyouhei has no idea why extension
* libraries should use this API.
*/
void rb_free_generic_ivar(VALUE obj);
/**
* Identical to rb_iv_get(), except it accepts the name as an ::ID instead of a
* C string.
*
* @param[in] obj Target object.
* @param[in] name Target instance variable to query.
* @retval RUBY_nil No such instance variable.
* @retval otherwise The value assigned to the instance variable.
*/
VALUE rb_ivar_get(VALUE obj, ID name);
/**
* Identical to rb_iv_set(), except it accepts the name as an ::ID instead of a
* C string.
*
* @param[out] obj Target object.
* @param[in] name Target instance variable.
* @param[in] val Value to assign.
* @exception rb_eFrozenError Can't modify `obj`.
* @exception rb_eArgError `obj` has too many instance variables.
* @return Passed value.
* @post An instance variable named `name` is defined if absent on
* `obj`, whose value is set to `val`.
*/
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val);
/**
* Queries if the instance variable is defined at the object. This roughly
* resembles `defined?(@name)` in `obj`'s context.
*
* @param[in] obj Target object.
* @param[in] name Target instance variable to query.
* @retval RUBY_Qtrue There is an instance variable.
* @retval RUBY_Qfalse No such instance variable.
*/
VALUE rb_ivar_defined(VALUE obj, ID name);
/**
* Iterates over an object's instance variables.
*
* @param[in] obj Target object.
* @param[in] func Callback function.
* @param[in] arg Passed as-is to the last argument of `func`.
*/
void rb_ivar_foreach(VALUE obj, int (*func)(ID name, VALUE val, st_data_t arg), st_data_t arg);
/**
* Number of instance variables defined on an object.
*
* @param[in] obj Target object.
* @return Number of instance variables defined on `obj`.
*/
st_index_t rb_ivar_count(VALUE obj);
/**
* Identical to rb_ivar_get()
*
* @param[in] obj Target object.
* @param[in] name Target instance variable to query.
* @retval RUBY_nil No such instance variable.
* @retval otherwise The value assigned to the instance variable.
*
* @internal
*
* Am I missing something? Why we have the same thing in different names?
*/
VALUE rb_attr_get(VALUE obj, ID name);
/**
* Resembles `Object#instance_variables`.
*
* @param[in] obj Target object to query.
* @return An array of instance variable names for the receiver.
* @note Simply defining an accessor does not create the corresponding
* instance variable.
*/
VALUE rb_obj_instance_variables(VALUE obj);
/**
* Resembles `Object#remove_instance_variable`.
*
* @param[out] obj Target object.
* @param[in] name Variable name to remove, either in Symbol or String.
* @return What was removed.
* @pre Instance variable named `name` is deleted from `obj`.
*/
VALUE rb_obj_remove_instance_variable(VALUE obj, VALUE name);
/**
* This API is mysterious. It has been there since the initial revision. No
* single bits of documents has ever been written. The function name doesn't
* describe anything. What should be passed to the argument, or what should be
* the return value, are not obvious. Yet it has evolved over time. The
* source code is written in counter-intuitive way (as of 3.0).
*
* Simply put, don't try to understand this API.
*/
void *rb_mod_const_at(VALUE, void*);
/**
* This is a variant of rb_mod_const_at(). As a result, it is also mysterious.
* It _seems_ it iterates over the ancestry tree of the module. But what that
* means is beyond a human brain.
*/
void *rb_mod_const_of(VALUE, void*);
/**
* This is another mysterious API that comes with no documents at all. It
* seems it expects some specific data structure for the passed pointer. But
* the details has never been made explicit. It seems nobody should use this
* API.
*/
VALUE rb_const_list(void*);
/**
* Resembles `Module#constants`. List up the constants defined at the
* receiver. This includes the names of constants in any included modules,
* unless `argv[0]` is ::RUBY_Qfalse.
*
* The implementation makes no guarantees about the order in which the
* constants are yielded.
*
* @param[in] argc Either 0 or 1.
* @param[in] argv Pointer to ::RUBY_Qfalse, if `argc == 1`.
* @param[in] recv Target namespace.
* @return An array of symbols, which are constant names under `recv`.
*/
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv);
/**
* Resembles `Module#remove_const`.
*
* @param[out] space Target namespace.
* @param[in] name Variable name to remove, either in Symbol or String.
* @return What was removed.
* @pre Constant named `space::name` is deleted.
* @note In case what was removed was in fact a module or a class, this
* operation does not affect its name. Which means when people
* for instance look at it using `p` etc., it still introduces
* itself using the deleted name. Can confuse people.
*/
VALUE rb_mod_remove_const(VALUE space, VALUE name);
/**
* Queries if the constant is defined at the namespace.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @retval RUBY_Qtrue There is a constant.
* @retval RUBY_Qfalse No such constant.
*
* @internal
*
* The return values are not typo! This function returns ruby values casted to
* `int`. Completely brain-damaged design.
*/
int rb_const_defined(VALUE space, ID name);
/**
* Identical to rb_const_defined(), except it doesn't look for parent classes.
* For instance `Array` is a toplevel constant, which is visible from
* everywhere. But this function does not take such things into account. It
* concerns only what is directly defined inside of the given namespace.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @retval RUBY_Qtrue There is a constant.
* @retval RUBY_Qfalse No such constant.
*
* @internal
*
* The return values are not typo! This function returns ruby values casted to
* `int`. Completely brain-damaged design.
*/
int rb_const_defined_at(VALUE space, ID name);
/**
* Identical to rb_const_defined(), except it returns false for private
* constants.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @retval RUBY_Qtrue There is a constant.
* @retval RUBY_Qfalse No such constant.
*
* @internal
*
* What does "from" mean? The name sounds quite cryptic.
*
* The return values are not typo! This function returns ruby values casted to
* `int`. Completely brain-damaged design.
*/
int rb_const_defined_from(VALUE space, ID name);
/**
* Identical to rb_const_defined(), except it returns the actual defined value.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @exception rb_eNameError No such constant.
* @return The defined constant.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_const_get(VALUE space, ID name);
/**
* Identical to rb_const_defined_at(), except it returns the actual defined
* value. It can also be seen as a routine identical to rb_const_get(), except
* it doesn't look for parent classes.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @exception rb_eNameError No such constant.
* @return The defined constant.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_const_get_at(VALUE space, ID name);
/**
* Identical to rb_const_defined_at(), except it returns the actual defined
* value. It can also be seen as a routine identical to rb_const_get(), except
* it doesn't return a private constant.
*
* @param[in] space Target namespace.
* @param[in] name Target name to query.
* @exception rb_eNameError No such constant.
* @return The defined constant.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_const_get_from(VALUE space, ID name);
/**
* Names a constant.
*
* @param[out] space Target namespace.
* @param[in] name Target name to query.
* @param[in] val Value to define.
* @exception rb_eTypeError `space` is not a module.
* @post `name` is a constant under `space`, whose value is `val`.
* @note You can reassign.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_const_set(VALUE space, ID name, VALUE val);
/**
* Identical to rb_mod_remove_const(), except it takes the name as ::ID instead
* of ::VALUE.
*
* @param[out] space Target namespace.
* @param[in] name Variable name to remove, either in Symbol or String.
* @return What was removed.
* @pre Constant named `space::name` is deleted.
* @note In case what was removed was in fact a module or a class, this
* operation does not affect its name. Which means when people
* for instance look at it using `p` etc., it still introduces
* itself using the deleted name. Can confuse people.
*/
VALUE rb_const_remove(VALUE space, ID name);
#if 0 /* EXPERIMENTAL: remove if no problem */
RBIMPL_ATTR_NORETURN()
/**
* This is the default implementation of `Module#const_missing`.
*
* @param[in] space Target namespace.
* @param[in] name Target name that is nonexistent.
* @exception rb_eNameError Always.
*/
VALUE rb_mod_const_missing(VALUE space, VALUE name);
#endif
/**
* Queries if the given class has the given class variable.
*
* @param[in] klass Target class.
* @param[in] name Name to query.
* @return RUBY_Qtrue Yes there is.
* @return RUBY_Qfalse No there isn't.
* @pre `klass` must be an instance of rb_cModule.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_cvar_defined(VALUE klass, ID name);
/**
* Assigns a value to a class variable.
*
* @param[out] klass Target class.
* @param[in] name Variable name.
* @param[in] val Value to be assigned.
* @post `klass` has a class variable named `name` whose value is `val`.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_cvar_set(VALUE klass, ID name, VALUE val);
/**
* Obtains a value from a class variable.
*
* @param[in] klass Target class.
* @param[in] name Variable name.
* @exception rb_eNameError Uninitialised class variable.
* @exception rb_eRuntimeError `[Bug#14541]` situation.
* @return Class variable named `name` under `klass`.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_cvar_get(VALUE klass, ID name);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_cvar_get(), except it takes additional "front" pointer.
* This extra parameter is a buffer, which will have the class where the
* queried class variable actually resides.
*
* @param[in] klass Target class.
* @param[in] name Variable name.
* @param[out] front Return buffer.
* @exception rb_eNameError Uninitialised class variable.
* @exception rb_eRuntimeError `[Bug#14541]` situation.
* @return Class variable named `name` under `klass`.
* @post `front` has the class object, which is an ancestor of `klass`,
* where the queried class variable actually resides.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
VALUE rb_cvar_find(VALUE klass, ID name, VALUE *front);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_cvar_set(), except it accepts C's string instead of ::ID.
*
* @param[out] klass Target class.
* @param[in] name Variable name.
* @param[in] val Value to be assigned.
* @post `klass` has a class variable named `name` whose value is `val`.
*/
void rb_cv_set(VALUE klass, const char *name, VALUE val);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_cvar_get(), except it accepts C's string instead of ::ID.
*
* @param[in] klass Target class.
* @param[in] name Variable name.
* @exception rb_eNameError Uninitialised class variable.
* @exception rb_eRuntimeError `[Bug#14541]` situation.
* @return Class variable named `name` under `klass`.
*/
VALUE rb_cv_get(VALUE klass, const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* @alias{rb_cv_set}
*
* @internal
*
* Am I missing something? Why we have the same thing in different names?
*/
void rb_define_class_variable(VALUE, const char*, VALUE);
/**
* Resembles `Module#class_variables`. List up the variables defined at the
* receiver. This includes the names of constants in any included modules,
* unless `argv[0]` is ::RUBY_Qfalse.
*
* The implementation makes no guarantees about the order in which the
* constants are yielded.
*
* @param[in] argc Either 0 or 1.
* @param[in] argv Pointer to ::RUBY_Qfalse, if `argc == 1`.
* @param[in] recv Target class.
* @return An array of symbols, which are class variable names under
* `recv`.
*/
VALUE rb_mod_class_variables(int argc, const VALUE *argv, VALUE recv);
/**
* Resembles `Module#remove_class_variable`.
*
* @param[out] mod Target class.
* @param[in] name Variable name to remove, either in Symbol or String.
* @return What was removed.
* @pre Instance variable named `name` is deleted from `obj`.
*/
VALUE rb_mod_remove_cvar(VALUE mod, VALUE name);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_VARIABLE_H */
include/ruby/internal/intern/sprintf.h 0000644 00000014504 15040330603 0014117 0 ustar 00 #ifndef RBIMPL_INTERN_SPRINTF_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SPRINTF_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Our own private `printf(3)`.
*/
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* sprintf.c */
/**
* Identical to rb_str_format(), except how the arguments are arranged.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv A format string, followed by its arguments.
* @return A rendered new instance of ::rb_cString.
*
* @internal
*
* You can safely pass NULL to `argv`. Doesn't make any sense though.
*/
VALUE rb_f_sprintf(int argc, const VALUE *argv);
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Ruby's extended `sprintf(3)`. We ended up reinventing the entire `printf`
* business because we don't want to depend on locales. OS-provided `printf`
* routines might or might not, which caused instabilities of the result
* strings.
*
* The format sequence is a mixture of format specifiers and other verbatim
* contents. Each format specifier starts with a `%`, and has the following
* structure:
*
* ```
* %[flags][width][.precision][length]conversion
* ```
*
* This function supports flags of ` `, `#`, `+`, `-`, `0`, width of
* non-negative decimal integer and `*`, precision of non-negative decimal
* integers and `*`, length of `L`, `h`, `t`, `z`, `l`, `ll`, `q`, conversions
* of `A`, `D`, `E`, `G`, `O`, `U`, `X`, `a`, `c`, `d`, `e`, `f`, `g`, `i`,
* `n`, `o`, `p`, `s`, `u`, `x`, and `%`. In case of `_WIN32` it also supports
* `I`. And additionally, it supports magical `PRIsVALUE` macro that can
* stringise arbitrary Ruby objects:
*
* ```CXX
* rb_sprintf("|%"PRIsVALUE"|", RUBY_Qtrue); // => "|true|"
* rb_sprintf("%+"PRIsVALUE, rb_stdin); // => "#<IO:<STDIN>>"
* ```
*
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ... Variadic number of contents to format.
* @return A rendered new instance of ::rb_cString.
*
* @internal
*
* :FIXME: We can improve this document.
*/
VALUE rb_sprintf(const char *fmt, ...);
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 0)
/**
* Identical to rb_sprintf(), except it takes a `va_list`.
*
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ap Contents to format.
* @return A rendered new instance of ::rb_cString.
*/
VALUE rb_vsprintf(const char *fmt, va_list ap);
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_sprintf(), except it renders the output to the specified
* object rather than creating a new one.
*
* @param[out] dst String to modify.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ... Variadic number of contents to format.
* @exception rb_eTypeError `dst` is not a String.
* @return Passed `dst`.
* @post `dst` has the rendered output appended to its end.
*/
VALUE rb_str_catf(VALUE dst, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
/**
* Identical to rb_str_catf(), except it takes a `va_list`. It can also be
* seen as a routine identical to rb_vsprintf(), except it renders the output
* to the specified object rather than creating a new one.
*
* @param[out] dst String to modify.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ap Contents to format.
* @exception rb_eTypeError `dst` is not a String.
* @return Passed `dst`.
* @post `dst` has the rendered output appended to its end.
*/
VALUE rb_str_vcatf(VALUE dst, const char *fmt, va_list ap);
/**
* Formats a string.
*
* Returns the string resulting from applying `fmt` to `argv`. The format
* sequence is a mixture of format specifiers and other verbatim contents.
* Each format specifier starts with a `%`, and has the following structure:
*
* ```
* %[flags][width][.precision]type
* ```
*
* ... which is different from that of rb_sprintf(). Because ruby has no
* `short` or `long`, there is no way to specify a "length" of an argument.
*
* This function supports flags of ` `, `#`, `+`, `-`, `<>`, `{}`, with of
* non-negative decimal integer and `$`, `*`, precision of non-negative decimal
* integer and `$`, `*`, type of `A`, `B`, `E`, `G`, `X`, `a`, `b`, `c`, `d`,
* `e`, `f`, `g`, `i`, `o`, `p`, `s`, `u`, `x`, `%`. This list is also
* (largely the same but) not identical to that of rb_sprintf().
*
* @param[in] argc Number of objects in `argv`.
* @param[in] argv Format arguments.
* @param[in] fmt A printf-like format specifier.
* @exception rb_eTypeError `fmt` is not a string.
* @exception rb_eArgError Failed to parse `fmt`.
* @return A rendered new instance of ::rb_cString.
* @note Everything it takes must be Ruby objects.
*
*/
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_SPRINTF_H */
include/ruby/internal/intern/load.h 0000644 00000022232 15040330603 0013346 0 ustar 00 #ifndef RBIMPL_INTERN_LOAD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_LOAD_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_f_require().
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* load.c */
/**
* Loads and executes the Ruby program in the given file.
*
* If the path is an absolute path (e.g. starts with `'/'`), the file will be
* loaded directly using the absolute path. If the path is an explicit
* relative path (e.g. starts with `'./'` or `'../'`), the file will be loaded
* using the relative path from the current directory. Otherwise, the file
* will be searched for in the library directories listed in the `$LOAD_PATH`.
* If the file is found in a directory, this function will attempt to load the
* file relative to that directory. If the file is not found in any of the
* directories in the `$LOAD_PATH`, the file will be loaded using the relative
* path from the current directory.
*
* If the file doesn't exist when there is an attempt to load it, a LoadError
* will be raised.
*
* If the `wrap` parameter is true, the loaded script will be executed under an
* anonymous module, protecting the calling program's global namespace. In no
* circumstance will any local variables in the loaded file be propagated to
* the loading environment.
*
* @param[in] path Pathname of a file to load.
* @param[in] wrap Either to load under an anonymous module.
* @exception rb_eTypeError `path` is not a string.
* @exception rb_eArgError `path` is broken as a pathname.
* @exception rb_eEncCompatError `path` is incompatible with pathnames.
* @exception rb_eLoadError `path` not found.
* @exception rb_eException Any exceptions while loading the contents.
*
* @internal
*
* It seems this function is under the rule of bootsnap's regime?
*/
void rb_load(VALUE path, int wrap);
/**
* Identical to rb_load(), except it avoids potential global escapes. Such
* global escapes include exceptions, `throw`, `break`, for example.
*
* It first evaluates the given file as rb_load() does. If no global escape
* occurred during the evaluation, it `*state` is set to zero on return.
* Otherwise, it sets `*state` to nonzero. If state is `NULL`, it is not set
* in both cases.
*
* @param[in] path Pathname of a file to load.
* @param[in] wrap Either to load under an anonymous module.
* @param[out] state State of execution.
* @post `*state` is set to zero if succeeded. Nonzero otherwise.
* @warning You have to clear the error info with `rb_set_errinfo(Qnil)` if
* you decide to ignore the caught exception.
* @see rb_load
* @see rb_protect
*
* @internal
*
* Though not a part of our public API, `state` is in fact an
* enum ruby_tag_type. You can see the potential "nonzero" values by looking
* at vm_core.h.
*/
void rb_load_protect(VALUE path, int wrap, int *state);
RBIMPL_ATTR_NONNULL(())
/**
* Queries if the given feature has already been loaded into the execution
* context. The "feature" head are things like `"json"` or `"socket"`.
*
* @param[in] feature Name of a library you want to know about.
* @retval 1 Yes there is.
* @retval 0 Not yet.
*/
int rb_provided(const char *feature);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_provided(), except it additionally returns the "canonical"
* name of the loaded feature. This can be handy when for instance you want to
* know the actually loaded library is either `foo.rb` or `foo.so`.
*
* @param[in] feature Name of a library you want to know about.
* @param[out] loading Return buffer.
* @retval 1 Yes there is.
* @retval 0 Not yet.
*/
int rb_feature_provided(const char *feature, const char **loading);
RBIMPL_ATTR_NONNULL(())
/**
* Declares that the given feature is already provided by someone else. This
* API can be handy when you have an extension called `foo.so` which, when
* required, also provides functionality of `bar.so`.
*
* @param[in] feature Name of a library which had already been provided.
* @post No further `require` would search `feature`.
*/
void rb_provide(const char *feature);
/**
* Identical to rb_require_string(), except it ignores the first argument for
* no reason. There seems to be no reason for 3rd party extension libraries to
* use it.
*
* @param[in] self Ignored. Can be anything.
* @param[in] feature Name of a feature, e.g. `"json"`.
* @exception rb_eLoadError No such feature.
* @exception rb_eRuntimeError `$"` is frozen; unable to push.
* @retval RUBY_Qtrue The feature is loaded for the first time.
* @retval RUBY_Qfalse The feature has already been loaded.
* @post `$"` is updated.
*/
VALUE rb_f_require(VALUE self, VALUE feature);
/**
* Finds and loads the given feature, if absent.
*
* If the feature is an absolute path (e.g. starts with `'/'`), the feature
* will be loaded directly using the absolute path. If the feature is an
* explicit relative path (e.g. starts with `'./'` or `'../'`), the feature
* will be loaded using the relative path from the current directory.
* Otherwise, the feature will be searched for in the library directories
* listed in the `$LOAD_PATH`.
*
* If the feature has the extension `".rb"`, it is loaded as a source file; if
* the extension is `".so"`, `".o"`, or `".dll"`, or the default shared library
* extension on the current platform, Ruby loads the shared library as a Ruby
* extension. Otherwise, Ruby tries adding `".rb"`, `".so"`, and so on to the
* name until found. If the file named cannot be found, a LoadError will be
* raised.
*
* For extension libraries the given feature may use any shared library
* extension. For example, on Linux you can require `"socket.dll"` to actually
* load `socket.so`.
*
* The absolute path of the loaded file is added to `$LOADED_FEATURES`. A file
* will not be loaded again if its path already appears in there.
*
* Any constants or globals within the loaded source file will be available in
* the calling program's global namespace. However, local variables will not
* be propagated to the loading environment.
*
* @param[in] feature Name of a feature, e.g. `"json"`.
* @exception rb_eLoadError No such feature.
* @exception rb_eRuntimeError `$"` is frozen; unable to push.
* @retval RUBY_Qtrue The feature is loaded for the first time.
* @retval RUBY_Qfalse The feature has already been loaded.
* @post `$"` is updated.
*/
VALUE rb_require_string(VALUE feature);
/**
* @name extension configuration
* @{
*/
/**
* Asserts that the extension library that calls this function is aware of
* Ractor. Multiple Ractors run without protecting each other. This doesn't
* interface well with C programs, unless designed with an in-depth
* understanding of how Ractors work. Extension libraries are shut out from
* Ractors by default. This API is to bypass that restriction. Once after it
* was called, successive calls to rb_define_method() etc. become definitions
* of methods that are aware of Ractors. The amendment would be in effect
* until the end of rb_require_string() etc.
*
* @param[in] flag Either the library is aware of Ractors or not.
* @post Methods would be callable form Ractors, if `flag` is true.
*/
void rb_ext_ractor_safe(bool flag);
/** @alias{rb_ext_ractor_safe} */
#define RB_EXT_RACTOR_SAFE(f) rb_ext_ractor_safe(f)
/**
* This macro is to provide backwards compatibility. It must be safe to do
* something like:
*
* ```CXX
* #ifdef HAVE_RB_EXT_RACTOR_SAFE
* rb_ext_ractor_safe(true);
* #endif
* ```
*/
#define HAVE_RB_EXT_RACTOR_SAFE 1
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_LOAD_H */
include/ruby/internal/intern/compar.h 0000644 00000005015 15040330603 0013710 0 ustar 00 #ifndef RBIMPL_INTERN_COMPAR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_COMPAR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_mComparable.
*/
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* bignum.c */
/**
* Canonicalises the passed `val`, which is the return value of `a <=> b`, into
* C's `{-1, 0, 1}`. This can be handy when you implement a callback function
* to pass to `qsort(3)` etc.
*
* @param[in] val Return value of a space ship operator.
* @param[in] a Comparison LHS.
* @param[in] b Comparison RHS.
* @exception rb_eArgError `a` and `b` are not comparable each other.
* @retval -1 `val` is less than zero.
* @retval 0 `val` is equal to zero.
* @retval 1 `val` is greater than zero.
*/
int rb_cmpint(VALUE val, VALUE a, VALUE b);
/* compar.c */
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
* Raises "comparison failed" error.
*
* @param[in] a Comparison LHS.
* @param[in] b Comparison RHS.
* @exception rb_eArgError `a` and `b` are not comparable each other.
*/
void rb_cmperr(VALUE a, VALUE b);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_COMPAR_H */
include/ruby/internal/intern/time.h 0000644 00000014526 15040330603 0013374 0 ustar 00 #ifndef RBIMPL_INTERN_TIME_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_TIME_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cTime.
*/
#include "ruby/internal/config.h"
#ifdef HAVE_TIME_H
# include <time.h> /* for time_t */
#endif
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
struct timespec;
struct timeval;
/* time.c */
RBIMPL_ATTR_NONNULL(())
/**
* Fills the current time into the given struct.
*
* @param[out] ts Return buffer.
* @exception rb_eSystemCallError Access denied for hardware clock.
* @post Current time is stored in `*ts`.
*/
void rb_timespec_now(struct timespec *ts);
/**
* Creates an instance of ::rb_cTime with the given time and the local
* timezone.
*
* @param[in] sec Seconds since the UNIX epoch.
* @param[in] usec Subsecond part, in microseconds resolution.
* @exception rb_eRangeError Cannot express the time.
* @return An allocated instance of ::rb_cTime.
*/
VALUE rb_time_new(time_t sec, long usec);
/**
* Identical to rb_time_new(), except it accepts the time in nanoseconds
* resolution.
*
* @param[in] sec Seconds since the UNIX epoch.
* @param[in] nsec Subsecond part, in nanoseconds resolution.
* @exception rb_eRangeError Cannot express the time.
* @return An allocated instance of ::rb_cTime.
*/
VALUE rb_time_nano_new(time_t sec, long nsec);
RBIMPL_ATTR_NONNULL(())
/**
* Creates an instance of ::rb_cTime, with given time and offset.
*
* @param[in] ts Time specifier.
* @param[in] offset Offset specifier, can take following values:
* - `INT_MAX`: `ts` is in local time.
* - `INT_MAX - 1`: `ts` is in UTC.
* - `-86400` to `86400`: fixed timezone.
* @exception rb_eArgError Malformed `offset`.
* @return An allocated instance of ::rb_cTime.
*/
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);
/**
* Identical to rb_time_timespec_new(), except it takes Ruby values instead of
* C structs.
*
* @param[in] timev Something numeric. Currently Integers, Rationals,
* and Floats are accepted.
* @param[in] off Offset specifier. As of 2.7 this argument is
* heavily extended to take following kinds of
* objects:
* - ::RUBY_Qundef ... means UTC.
* - ::rb_cString ... "+12:34" etc.
* - A mysterious "zone" object. This is largely
* undocumented. However the initial intent was
* that we want to accept
* `ActiveSupport::TimeZone` here. Other gems
* could also be possible... But how to make an
* acceptable class is beyond this document.
* @exception rb_eArgError Malformed `off`.
* @return An allocated instance of ::rb_cTime.
*/
VALUE rb_time_num_new(VALUE timev, VALUE off);
/**
* Creates a "time interval". This basically converts an instance of
* ::rb_cNumeric into a struct `timeval`, but for instance negative time
* interval must not exist.
*
* @param[in] num An instance of ::rb_cNumeric.
* @exception rb_eArgError `num` is negative.
* @exception rb_eRangeError `num` is out of range of `timeval::tv_sec`.
* @return A struct that represents the identical time to `num`.
*/
struct timeval rb_time_interval(VALUE num);
/**
* Converts an instance of rb_cTime to a struct timeval that represents the
* identical point of time. It can also take something numeric; would consider
* it as a UNIX time then.
*
* @param[in] time Instance of either ::rb_cTime or ::rb_cNumeric.
* @exception rb_eRangeError `time` is out of range of `timeval::tv_sec`.
* @return A struct that represents the identical time to `num`.
*/
struct timeval rb_time_timeval(VALUE time);
/**
* Identical to rb_time_timeval(), except for return type.
*
* @param[in] time Instance of either ::rb_cTime or ::rb_cNumeric.
* @exception rb_eRangeError `time` is out of range of `timeval::tv_sec`.
* @return A struct that represents the identical time to `num`.
*/
struct timespec rb_time_timespec(VALUE time);
/**
* Identical to rb_time_interval(), except for return type.
*
* @param[in] num An instance of ::rb_cNumeric.
* @exception rb_eArgError `num` is negative.
* @exception rb_eRangeError `num` is out of range of `timespec::tv_sec`.
* @return A struct that represents the identical time to `num`.
*/
struct timespec rb_time_timespec_interval(VALUE num);
/**
* Queries the offset, in seconds between the time zone of the time and the
* UTC.
*
* @param[in] time An instance of ::rb_cTime.
* @return Numeric offset.
*/
VALUE rb_time_utc_offset(VALUE time);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_TIME_H */
include/ruby/internal/intern/file.h 0000644 00000022576 15040330603 0013361 0 ustar 00 #ifndef RBIMPL_INTERN_FILE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_FILE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cFile.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* file.c */
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_file_expand_path(), except how arguments are passed.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Filename, and base directory, in that order.
* @exception rb_eArgError Wrong `argc`.
* @exception rb_eTypeError Non-string passed.
* @exception rb_eEncCompatError No conversion from arguments to a path.
* @return Expanded path.
*
* @internal
*
* It seems nobody actually uses this function right now. Maybe delete it?
*/
VALUE rb_file_s_expand_path(int argc, const VALUE *argv);
/**
* Identical to rb_file_absolute_path(), except it additionally understands
* `~`. If a given pathname starts with `~someone/`, that part expands to the
* user's home directory (or that of current process' owner's in case of `~/`).
*
* @param[in] fname Relative file name.
* @param[in] dname Lookup base directory name, or in case
* ::RUBY_Qnil is passed the process' current
* working directory is assumed.
* @exception rb_eArgError Home directory is not absolute.
* @exception rb_eTypeError Non-string passed.
* @exception rb_eEncCompatError No conversion from arguments to a path.
* @return Expanded path.
*/
VALUE rb_file_expand_path(VALUE fname, VALUE dname);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_file_absolute_path(), except how arguments are passed.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Filename, and base directory, in that order.
* @exception rb_eArgError Wrong `argc`.
* @exception rb_eTypeError Non-string passed.
* @exception rb_eEncCompatError No conversion from arguments to a path.
* @return Expanded path.
*
* @internal
*
* It seems nobody actually uses this function right now. Maybe delete it?
*/
VALUE rb_file_s_absolute_path(int argc, const VALUE *argv);
/**
* Maps a relative path to its absolute representation. Relative paths are
* referenced from the passed directory name, or from the process' current
* working directory in case ::RUBY_Qnil is passed.
*
* @param[in] fname Relative file name.
* @param[in] dname Lookup base directory name, or in case
* ::RUBY_Qnil is passed the process' current
* working directory is assumed.
* @exception rb_eArgError Strings contain NUL bytes.
* @exception rb_eTypeError Non-string passed.
* @exception rb_eEncCompatError No conversion from arguments to a path.
* @return Expanded path.
*/
VALUE rb_file_absolute_path(VALUE fname, VALUE dname);
/**
* Strips a file path's last component (and trailing separators if any). This
* function is relatively simple on POSIX environments; just splits the input
* with `/`, strips the last one, if something remains joins them again,
* otherwise the return value is `"."`. However when it comes to Windows this
* function is quite very much complicated. We have to take UNC etc. into
* account. So for instance `"C:foo"`'s dirname is `"C:."`.
*
* @param[in] fname File name to strip.
* @exception rb_eTypeError `fname` is not a String.
* @exception rb_eArgError `fname` contains NUL bytes.
* @exception rb_eEncCompatError `fname`'s encoding is not path-compat.
* @return A dirname of `fname`.
* @note This is a "pure" operation; it computes the return value solely
* from the passed object and never does any file IO.
*/
VALUE rb_file_dirname(VALUE fname);
RBIMPL_ATTR_NONNULL(())
/**
* Resolves a feature's path. This function takes for instance `"json"` and
* `[".so", ".rb"]`, and iterates over the `$LOAD_PATH` to see if there is
* either `json.so` or `json.rb` in the directory.
*
* This is not what everything `require` does, but at least `require` is built
* on top of it.
*
* @param[in,out] feature File to search, and return buffer.
* @param[in] exts List of file extensions.
* @exception rb_eTypeError `feature` is not a String.
* @exception rb_eArgError `feature` contains NUL bytes.
* @exception rb_eEncCompatError `feature`'s encoding is not path-compat.
* @retval 0 Not found
* @retval otherwise Found index in `ext`, plus one.
* @post `*feature` is a resolved path.
*/
int rb_find_file_ext(VALUE *feature, const char *const *exts);
/**
* Identical to rb_find_file_ext(), except it takes a feature name and is
* extension at once, e.g. `"json.rb"`. This difference is much like how
* `require` and `load` are different.
*
* @param[in] path A path relative to `$LOAD_PATH`.
* @exception rb_eTypeError `path` is not a String.
* @exception rb_eArgError `path` contains NUL bytes.
* @exception rb_eEncCompatError `path`'s encoding is not path-compat.
* @return Expanded path.
*/
VALUE rb_find_file(VALUE path);
/**
* Queries if the given path is either a directory, or a symlink that
* (potentially recursively) points to such thing.
*
* @param[in] _ Ignored (why...?)
* @param[in] path String, or IO. In case of IO it issues
* `fstat(2)` instead of `stat(2)`.
* @exception rb_eFrozenError `path` is a frozen IO (why...?)
* @exception rb_eTypeError `path` is neither String nor IO.
* @exception rb_eArgError `path` contains NUL bytes.
* @exception rb_eEncCompatError `path`'s encoding is not path-compat.
* @retval RUBY_Qtrue `path` is a directory.
* @retval RUBY_Qfalse Otherwise.
*/
VALUE rb_file_directory_p(VALUE _, VALUE path);
/**
* Converts a string into an "OS Path" encoding, if any. In most operating
* systems there are no such things like per-OS default encoding of filename.
* For them this function is no-op. However most notably on MacOS, pathnames
* are UTF-8 encoded. It converts the given string into such encoding.
*
* @param[in] path An instance of ::rb_cString.
* @exception rb_eEncCompatError `path`'s encoding is not path-compat.
* @return `path`'s contents converted to the OS' path encoding.
*/
VALUE rb_str_encode_ospath(VALUE path);
RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
* Queries if the given path is an absolute path. On POSIX environments it is
* as easy as `path[0] == '/'`. However on Windows, drive letters and UNC
* paths are also taken into account.
*
* @param[in] path A possibly relative path string.
* @retval 1 `path` is absolute.
* @retval 0 `path` is relative.
*/
int rb_is_absolute_path(const char *path);
/**
* Queries the file size of the given file. Because this function calls
* `fstat(2)` internally, it is a failure to pass a closed file to this
* function.
*
* This function flushes the passed file's buffer if any. Can take time.
*
* @param[in] file A file object.
* @exception rb_eFrozenError `file` is frozen.
* @exception rb_eIOError `file` is closed.
* @exception rb_eSystemCallError Permission denied etc.
* @exception rb_eNoMethodError The given non-file object doesn't respond
* to `#size`.
* @return The size of the passed file.
* @note Passing a non-regular file such as a UNIX domain socket to this
* function is not a failure. But the return value is
* unpredictable. POSIX's `<sys/stat.h>` states that "the use of
* this field is unspecified" then.
*/
rb_off_t rb_file_size(VALUE file);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_FILE_H */
include/ruby/internal/intern/enumerator.h 0000644 00000030206 15040330603 0014610 0 ustar 00 #ifndef RBIMPL_INTERN_ENUMERATOR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ENUMERATOR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cEnumerator.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/intern/eval.h" /* rb_frame_this_func */
#include "ruby/internal/iterator.h" /* rb_block_given_p */
#include "ruby/internal/symbol.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the type of functions that rb_enumeratorize_with_size() expects. In
* theory an enumerator can have indefinite number of elements, but in practice
* it often is the case we can compute the size of an enumerator beforehand.
* If your enumerator has such property, supply a function that calculates such
* values.
*
* @param[in] recv The original receiver of the enumerator.
* @param[in] argv Arguments passed to `Object#enum_for` etc.
* @param[in] eobj The enumerator object.
* @return The size of `eobj`, in ::rb_cNumeric, or ::RUBY_Qnil if the size
* is not known until we actually iterate.
*/
typedef VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj);
/**
* Decomposed `Enumerator::ArithmeicSequence`. This is a subclass of
* ::rb_cEnumerator, which represents a sequence of numbers with common
* difference. Internal data structure of the class is opaque to users, but
* you can obtain a decomposed one using rb_arithmetic_sequence_extract().
*/
typedef struct {
VALUE begin; /**< "Left" or "lowest" endpoint of the sequence. */
VALUE end; /**< "Right" or "highest" endpoint of the sequence.*/
VALUE step; /**< Step between a sequence. */
int exclude_end; /**< Whether the endpoint is open or closed. */
} rb_arithmetic_sequence_components_t;
/* enumerator.c */
/**
* Constructs an enumerator. This roughly resembles `Object#enum_for`.
*
* @param[in] recv A receiver of `meth`.
* @param[in] meth Method ID in a symbol object.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to `meth`.
* @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol.
* @return A new instance of ::rb_cEnumerator which, when yielded,
* enumerates by calling `meth` on `recv` with `argv`.
*/
VALUE rb_enumeratorize(VALUE recv, VALUE meth, int argc, const VALUE *argv);
/**
* Identical to rb_enumeratorize(), except you can additionally specify the
* size function of return value.
*
* @param[in] recv A receiver of `meth`.
* @param[in] meth Method ID in a symbol object.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to `meth`.
* @param[in] func Size calculator.
* @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol.
* @return A new instance of ::rb_cEnumerator which, when yielded,
* enumerates by calling `meth` on `recv` with `argv`.
* @note `func` can be zero, which means the size is unknown.
*/
VALUE rb_enumeratorize_with_size(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func);
/**
* Identical to rb_enumeratorize_with_func(), except you can specify how to
* handle the last element of the given array.
*
* @param[in] recv A receiver of `meth`.
* @param[in] meth Method ID in a symbol object.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to `meth`.
* @param[in] func Size calculator.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol.
* @return A new instance of ::rb_cEnumerator which, when yielded,
* enumerates by calling `meth` on `recv` with `argv`.
* @note `func` can be zero, which means the size is unknown.
*/
VALUE rb_enumeratorize_with_size_kw(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func, int kw_splat);
RBIMPL_ATTR_NONNULL(())
/**
* Extracts components of the passed arithmetic sequence. This can be seen as
* an extended version of rb_range_values().
*
* @param[in] as Target instance of `Enumerator::ArithmericSequence`.
* @param[out] buf Decomposed results buffer.
* @return 0 `as` is not `Enumerator::ArithmericSequence`.
* @return 1 Success.
* @post `buf` is filled.
*/
int rb_arithmetic_sequence_extract(VALUE as, rb_arithmetic_sequence_components_t *buf);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_range_beg_len(), except it takes an instance of
* `Enumerator::ArithmericSequence`.
*
* @param[in] as An `Enumerator::ArithmericSequence` instance.
* @param[out] begp Return value buffer.
* @param[out] lenp Return value buffer.
* @param[out] stepp Return value buffer.
* @param[in] len Updated length.
* @param[in] err In case `len` is out of range...
* - `0`: returns ::RUBY_Qnil.
* - `1`: raises ::rb_eRangeError.
* - `2`: `beg` and `len` expanded accordingly.
* @exception rb_eRangeError `as` cannot fit into `long`.
* @retval RUBY_Qfalse `as` is not `Enumerator::ArithmericSequence`.
* @retval RUBY_Qnil `len` is out of `as` but `err` is zero.
* @retval RUBY_Qtrue Otherwise.
* @post `beg` is the (possibly updated) left endpoint.
* @post `len` is the (possibly updated) length of the range.
*
* @internal
*
* Currently no 3rd party applications of this function is found. But that can
* be because this function is relatively new.
*/
VALUE rb_arithmetic_sequence_beg_len_step(VALUE as, long *begp, long *lenp, long *stepp, long len, int err);
RBIMPL_SYMBOL_EXPORT_END()
/** @cond INTERNAL_MACRO */
#ifndef RUBY_EXPORT
# define rb_enumeratorize_with_size(obj, id, argc, argv, size_fn) \
rb_enumeratorize_with_size(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn))
# define rb_enumeratorize_with_size_kw(obj, id, argc, argv, size_fn, kw_splat) \
rb_enumeratorize_with_size_kw(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn), kw_splat)
#endif
/** @endcond */
/**
* This is an implementation detail of #RETURN_SIZED_ENUMERATOR(). You could
* use it directly, but can hardly be handy.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @param[in] size_fn Size calculator.
* @return A new instance of ::rb_cEnumerator which, when yielded,
* enumerates by calling the current method on `recv` with `argv`.
*/
#define SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \
(argc), (argv), (size_fn))
/**
* This is an implementation detail of #RETURN_SIZED_ENUMERATOR_KW(). You
* could use it directly, but can hardly be handy.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @param[in] size_fn Size calculator.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @return A new instance of ::rb_cEnumerator which, when yielded,
* enumerates by calling the current method on `recv` with `argv`.
*/
#define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \
rb_enumeratorize_with_size_kw((obj), ID2SYM(rb_frame_this_func()), \
(argc), (argv), (size_fn), (kw_splat))
/**
* This roughly resembles `return enum_for(__callee__) unless block_given?`.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @param[in] size_fn Size calculator.
* @note This macro may return inside.
*/
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) do { \
if (!rb_block_given_p()) \
return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \
} while (0)
/**
* Identical to #RETURN_SIZED_ENUMERATOR(), except you can specify how to
* handle the last element of the given array.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @param[in] size_fn Size calculator.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @note This macro may return inside.
*/
#define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \
if (!rb_block_given_p()) \
return SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat); \
} while (0)
/**
* Identical to #RETURN_SIZED_ENUMERATOR(), except its size is unknown.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @note This macro may return inside.
*/
#define RETURN_ENUMERATOR(obj, argc, argv) \
RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)
/**
* Identical to #RETURN_SIZED_ENUMERATOR_KW(), except its size is unknown. It
* can also be seen as a routine identical to #RETURN_ENUMERATOR(), except you
* can specify how to handle the last element of the given array.
*
* @param[in] obj A receiver.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arguments passed to the current method.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @note This macro may return inside.
*/
#define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) \
RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, 0, kw_splat)
#endif /* RBIMPL_INTERN_ENUMERATOR_H */
include/ruby/internal/intern/range.h 0000644 00000007747 15040330603 0013541 0 ustar 00 #ifndef RBIMPL_INTERN_RANGE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RANGE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cRange.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* range.c */
/**
* Creates a new Range.
*
* @param[in] beg "Left" or "lowest" endpoint of the range.
* @param[in] end "Right" or "highest" endpoint of the range.
* @param[in] excl Whether the range is open-ended.
* @exception rb_eArgError `beg` and `end` are not comparable.
* @note These days both endpoints can be ::RUBY_Qnil, which means that
* endpoint is unbound.
*/
VALUE rb_range_new(VALUE beg, VALUE end, int excl);
RBIMPL_ATTR_NONNULL(())
/**
* Deconstructs a numerical range. As the arguments are `long` based, it
* expects everything are in the `long` domain.
*
* @param[in] range A range of numerical endpoints.
* @param[out] begp Return value buffer.
* @param[out] lenp Return value buffer.
* @param[in] len Updated length.
* @param[in] err In case `len` is out of range...
* - `0`: returns ::RUBY_Qnil.
* - `1`: raises ::rb_eRangeError.
* - `2`: `beg` and `len` expanded accordingly.
* @exception rb_eTypeError `range` is not a numerical range.
* @exception rb_eRangeError `range` cannot fit into `long`.
* @retval RUBY_Qfalse `range` is not an ::rb_cRange.
* @retval RUBY_Qnil `len` is out of `range` but `err` is zero.
* @retval RUBY_Qtrue Otherwise.
* @post `beg` is the (possibly updated) left endpoint.
* @post `len` is the (possibly updated) length of the range.
*
* @internal
*
* The complex error handling switch reflects the fact that `Array#[]=` and
* `String#[]=` behave differently when they take ranges.
*/
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err);
RBIMPL_ATTR_NONNULL(())
/**
* Deconstructs a range into its components.
*
* @param[in] range Range or range-ish object.
* @param[out] begp Return value buffer.
* @param[out] endp Return value buffer.
* @param[out] exclp Return value buffer.
* @retval RUBY_Qfalse `range` is not an instance of ::rb_cRange.
* @retval RUBY_Qtrue Argument pointers are updated.
* @post `*begp` is the left endpoint of the range.
* @post `*endp` is the right endpoint of the range.
* @post `*exclp` is whether the range is open-ended or not.
*/
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_RANGE_H */
include/ruby/internal/intern/enum.h 0000644 00000005513 15040330603 0013376 0 ustar 00 #ifndef RBIMPL_INTERN_ENUM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ENUM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_mEnumerable.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* enum.c */
/**
* Basically identical to rb_ary_new_form_values(), except it returns something
* different when `argc` < 2.
*
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Arbitrary objects.
* @retval RUBY_Qnil `argc` is zero.
* @retval argv[0] `argc` is one.
* @retval otherwise Otherwise.
*
* @internal
*
* What is this business? Well, this function is about `yield`'s taking
* multiple values. Consider following user-defined class:
*
* ```ruby
* class Foo
* include Enumerable
*
* def each
* yield :q, :w, :e, :r
* end
* end
*
* Foo.new.each_with_object([]) do |i, j|
* j << i # ^^^ <- What to expect for `i`?
* end
* ```
*
* Here, `Foo#each_with_object` is in fact `Enumerable#each_with_object`, which
* doesn't know what would be yielded. Yet, it has to take a block of arity 2.
* This function is used here, to "pack" arbitrary number of yielded objects
* into one.
*
* If people want to implement their own `Enumerable#each_with_object` this API
* can be handy. Though @shyouhei suspects it is relatively rare for 3rd party
* extension libraries to have such things. Also `Enumerable#each_entry` is
* basically this function exposed as a Ruby method.
*/
VALUE rb_enum_values_pack(int argc, const VALUE *argv);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_ENUM_H */
include/ruby/internal/anyargs.h 0000644 00000110607 15040330603 0012600 0 ustar 00 #ifndef RBIMPL_ANYARGS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ANYARGS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Function overloads to issue warnings around #ANYARGS.
*
* For instance ::rb_define_method takes a pointer to #ANYARGS -ed functions,
* which in fact varies 18 different prototypes. We still need to preserve
* #ANYARGS for storages but why not check the consistencies if possible. With
* those complex macro overlays defined in this header file, use of a function
* pointer gets checked against the corresponding arity argument.
*
* ### Q&A ###
*
* - Q: Where did the magic number "18" came from in the description above?
*
* - A: Count the case branch of `vm_method.c:call_cfunc_invoker_func()`. Note
* also that the 18 branches has lasted for at least 25 years. See also
* commit 200e0ee2fd3c1c006c528874a88f684447215524.
*
* - Q: What is this `__weakref__` thing?
*
* - A: That is a kind of function overloading mechanism that GCC provides. In
* this case for instance `rb_define_method_00` is an alias of
* ::rb_define_method, with a strong type.
*
* - Q: What is this `__transparent_union__` thing?
*
* A: That is another kind of function overloading mechanism that GCC
* provides. In this case the attributed function pointer is either
* `VALUE(*)(int,VALUE*,VALUE)` or `VALUE(*)(int,const VALUE*,VALUE)`.
*
* This is better than `void*` or #ANYARGS because we can reject all other
* possibilities than the two.
*
* - Q: What does this #rb_define_method macro mean?
*
* - A: It selects appropriate alias of the ::rb_define_method function,
* depending on the last (arity) argument.
*
* - Q: Why the special case for ::rb_f_notimplement ?
*
* - A: Function pointer to ::rb_f_notimplement is special cased in
* `vm_method.c:rb_add_method_cfunc()`. That should be handled by the
* `__builtin_choose_expr` chain inside of #rb_define_method macro
* expansion. In order to do so, comparison like
* `(func == rb_f_notimplement)` is inappropriate for
* `__builtin_choose_expr`'s expression (which must be a compile-time
* integer constant but the address of ::rb_f_notimplement is not fixed
* until the linker). Instead we are using
* `__builtin_types_compatible_p`, and in doing so we need to distinguish
* ::rb_f_notimplement from others, by type.
*/
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/weakref.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/config.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/vm.h"
#include "ruby/internal/method.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"
#if defined(__cplusplus)
# include "ruby/backward/cxxanyargs.hpp"
#elif defined(_WIN32) || defined(__CYGWIN__)
# /* Skip due to [Bug #16134] */
#elif ! RBIMPL_HAS_ATTRIBUTE(transparent_union)
# /* :TODO: improve here, please find a way to support. */
#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* :TODO: improve here, please find a way to support. */
#else
# /** @cond INTERNAL_MACRO */
# if ! defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
# define RBIMPL_CFUNC_IS_rb_f_notimplement(f) 0
# else
# define RBIMPL_CFUNC_IS_rb_f_notimplement(f) \
__builtin_types_compatible_p( \
__typeof__(f), \
__typeof__(rb_f_notimplement))
# endif
# if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) (falsy)
# else
# define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) \
__builtin_choose_expr( \
__builtin_choose_expr( \
__builtin_constant_p(expr), \
(expr), 0), \
(truthy), (falsy))
# endif
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_singleton_method_m2, rb_define_singleton_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_singleton_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_singleton_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_singleton_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_singleton_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_singleton_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_singleton_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_singleton_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_singleton_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_singleton_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_singleton_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_singleton_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_singleton_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_singleton_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_singleton_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_singleton_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_singleton_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_singleton_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_protected_method_m2, rb_define_protected_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_protected_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_protected_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_protected_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_protected_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_protected_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_protected_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_protected_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_protected_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_protected_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_protected_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_protected_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_protected_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_protected_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_protected_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_protected_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_protected_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_protected_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_private_method_m2, rb_define_private_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_private_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_private_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_private_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_private_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_private_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_private_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_private_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_private_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_private_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_private_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_private_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_private_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_private_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_private_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_private_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_private_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_private_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_module_function_m2, rb_define_module_function_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_module_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_module_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_module_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_module_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_module_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_module_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_module_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_module_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_module_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_module_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_module_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_module_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_module_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_module_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_module_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_module_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_module_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_global_function_m2, rb_define_global_function_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_global_function_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_global_function_00, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_global_function_01, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_global_function_02, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_global_function_03, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_global_function_04, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_global_function_05, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_global_function_06, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_global_function_07, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_global_function_08, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_global_function_09, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_global_function_10, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_global_function_11, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_global_function_12, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_global_function_13, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_global_function_14, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_global_function_15, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_id_m2, rb_define_method_id_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_id_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_id_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_id_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_id_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_id_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_id_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_id_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_id_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_id_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_id_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_id_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_id_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_id_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_id_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_id_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_id_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_id_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_m2, rb_define_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) == 0, rb_define_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) == 1, rb_define_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) == 2, rb_define_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) == 3, rb_define_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) == 4, rb_define_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) == 5, rb_define_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) == 6, rb_define_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) == 7, rb_define_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) == 8, rb_define_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) == 9, rb_define_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
# define RBIMPL_ANYARGS_ATTRSET(sym) RBIMPL_ATTR_MAYBE_UNUSED() RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_WEAKREF(sym)
# define RBIMPL_ANYARGS_DECL(sym, ...) \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _notimpl(__VA_ARGS__, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m2(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _01(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _02(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _03(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _04(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _05(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _06(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _07(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _08(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _09(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _10(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _11(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _12(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _13(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _14(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _15(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
RBIMPL_ANYARGS_DECL(rb_define_singleton_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_protected_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_private_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_module_function, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_global_function, const char *)
RBIMPL_ANYARGS_DECL(rb_define_method_id, VALUE, ID)
RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
/** @endcond */
/**
* @brief Defines klass\#mid.
* @see ::rb_define_method
* @param klass Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of klass\#mid.
* @param arity Arity of klass\#mid.
*/
#define rb_define_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
/**
* @brief Defines klass\#mid.
* @see ::rb_define_method_id
* @param klass Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of klass\#mid.
* @param arity Arity of klass\#mid.
*/
#define rb_define_method_id(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_method_id((arity), (func))((klass), (mid), (func), (arity))
/**
* @brief Defines obj.mid.
* @see ::rb_define_singleton_method
* @param obj Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of obj.mid.
* @param arity Arity of obj.mid.
*/
#define rb_define_singleton_method(obj, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method((arity), (func))((obj), (mid), (func), (arity))
/**
* @brief Defines klass\#mid and make it protected.
* @see ::rb_define_protected_method
* @param klass Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of klass\#mid.
* @param arity Arity of klass\#mid.
*/
#define rb_define_protected_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method((arity), (func))((klass), (mid), (func), (arity))
/**
* @brief Defines klass\#mid and make it private.
* @see ::rb_define_private_method
* @param klass Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of klass\#mid.
* @param arity Arity of klass\#mid.
*/
#define rb_define_private_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_private_method((arity), (func))((klass), (mid), (func), (arity))
/**
* @brief Defines mod\#mid and make it a module function.
* @see ::rb_define_module_function
* @param mod Where the method lives.
* @param mid Name of the defining method.
* @param func Implementation of mod\#mid.
* @param arity Arity of mod\#mid.
*/
#define rb_define_module_function(mod, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_module_function((arity), (func))((mod), (mid), (func), (arity))
/**
* @brief Defines ::rb_mKerbel \#mid.
* @see ::rb_define_global_function
* @param mid Name of the defining method.
* @param func Implementation of ::rb_mKernel \#mid.
* @param arity Arity of ::rb_mKernel \#mid.
*/
#define rb_define_global_function(mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_global_function((arity), (func))((mid), (func), (arity))
#endif /* __cplusplus */
/**
* This macro is to properly cast a function parameter of *_define_method
* family. It has been around since 1.x era so you can maximise backwards
* compatibility by using it.
*
* ```CXX
* rb_define_method(klass, "method", RUBY_METHOD_FUNC(func), arity);
* ```
*
* @param func A pointer to a function that implements a method.
*/
#if ! defined(RUBY_DEVEL)
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
#elif ! RUBY_DEVEL
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
#elif ! defined(rb_define_method)
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
#else
# define RUBY_METHOD_FUNC(func) (func)
#endif
#endif /* RBIMPL_ANYARGS_H */
include/ruby/internal/dosish.h 0000644 00000006250 15040330603 0012423 0 ustar 00 #ifndef RBIMPL_DOSISH_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_DOSISH_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Support for so-called dosish systems.
*/
#ifdef __CYGWIN__
#undef _WIN32
#endif
#if defined(_WIN32)
/*
DOSISH mean MS-Windows style filesystem.
But you should use more precise macros like DOSISH_DRIVE_LETTER, PATH_SEP,
ENV_IGNORECASE or CASEFOLD_FILESYSTEM.
*/
#define DOSISH 1
# define DOSISH_DRIVE_LETTER
#endif
#ifdef _WIN32
#include "ruby/win32.h"
#endif
/** The delimiter of `PATH` environment variable. */
#if defined(DOSISH)
#define PATH_SEP ";"
#else
#define PATH_SEP ":"
#endif
/** Identical to #PATH_SEP, except it is of type `char`. */
#define PATH_SEP_CHAR PATH_SEP[0]
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* For historical interests: there was an operating system called Human68k
* which used an environment variable called `"path"` for this purpose.
*/
#define PATH_ENV "PATH"
#if defined(DOSISH)
#define ENV_IGNORECASE
#endif
/**
* Stone age assumption was that an operating system supports only one file
* system at a moment. This macro was to detect if such (one and only) file
* system has case sensitivity. This assumption is largely not true any
* longer; most operating systems can mount many kinds of file systems side by
* side. Also there are file systems that do or do not ignore cases depending
* on configuration (e.g. EXT4's `casefold` feature).
*
* This macro is still used internally (for instance Ruby level constant
* `File::FNM_SYSCASE` depends on it), but it is basically a wrong idea for you
* to use it today. Please just find another way.
*/
#ifndef CASEFOLD_FILESYSTEM
# if defined DOSISH
# define CASEFOLD_FILESYSTEM 1
# else
# define CASEFOLD_FILESYSTEM 0
# endif
#endif
#endif /* RBIMPL_DOSISH_H */
include/ruby/internal/warning_push.h 0000644 00000011644 15040330603 0013641 0 ustar 00 #ifndef RBIMPL_WARNING_PUSH_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_WARNING_PUSH_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_WARNING_PUSH.
*
* ### Q&A ###
*
* Q: Why all the macros defined in this file are function-like macros?
*
* A: Sigh. This is because of Doxygen. Its `SKIP_FUNCTION_MACROS = YES`
* configuration setting requests us that if we want it to ignore these
* macros, then we have to do two things: (1) let them be defined as
* function-like macros, and (2) place them separately in their own line,
* like below:
*
* ```CXX
* // NG -- foo's type considered something like `unsigned int`.
* RBIMPL_WARNING_PUSH
* int foo(void);
* RBIMPL_WARNING_POP
*
* // OK -- the macros are ignored by Doxygen.
* RBIMPL_WARNING_PUSH()
* int foo(void);
* RBIMPL_WARNING_POP()
* ```
*/
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/compiler_since.h"
#if defined(__DOXYGEN__)
/**
* @private
*
* Pushes compiler warning state.
*/
#define RBIMPL_WARNING_PUSH() __pragma(warning(push))
/**
* @private
*
* Pops compiler warning state.
*/
#define RBIMPL_WARNING_POP() __pragma(warning(pop))
/**
* @private
*
* Turns a warning into a fatal error.
*
* @param flag A flag that represents the kind of warnings.
*/
#define RBIMPL_WARNING_ERROR(flag) __pragma(warning(error: flag))
/**
* @private
*
* Suppresses a warning.
*
* @param flag A flag that represents the kind of warnings.
*/
#define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))
#elif RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
# /* Not sure exactly when but it seems VC++ 6.0 is a version with it.*/
# define RBIMPL_WARNING_PUSH() __pragma(warning(push))
# define RBIMPL_WARNING_POP() __pragma(warning(pop))
# define RBIMPL_WARNING_ERROR(flag) __pragma(warning(error: flag))
# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))
#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# define RBIMPL_WARNING_PUSH() __pragma(warning(push))
# define RBIMPL_WARNING_POP() __pragma(warning(pop))
# define RBIMPL_WARNING_ERROR(flag) __pragma(warning(error: flag))
# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))
#elif RBIMPL_COMPILER_IS(Clang) || RBIMPL_COMPILER_IS(Apple)
# /* Not sure exactly when but it seems LLVM 2.6.0 is a version with it. */
# define RBIMPL_WARNING_PRAGMA0(x) _Pragma(# x)
# define RBIMPL_WARNING_PRAGMA1(x) RBIMPL_WARNING_PRAGMA0(clang diagnostic x)
# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
# define RBIMPL_WARNING_PUSH() RBIMPL_WARNING_PRAGMA1(push)
# define RBIMPL_WARNING_POP() RBIMPL_WARNING_PRAGMA1(pop)
# define RBIMPL_WARNING_ERROR(flag) RBIMPL_WARNING_PRAGMA2(error, flag)
# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)
#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# /* https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html */
# define RBIMPL_WARNING_PRAGMA0(x) _Pragma(# x)
# define RBIMPL_WARNING_PRAGMA1(x) RBIMPL_WARNING_PRAGMA0(GCC diagnostic x)
# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
# define RBIMPL_WARNING_PUSH() RBIMPL_WARNING_PRAGMA1(push)
# define RBIMPL_WARNING_POP() RBIMPL_WARNING_PRAGMA1(pop)
# define RBIMPL_WARNING_ERROR(flag) RBIMPL_WARNING_PRAGMA2(error, flag)
# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)
#else
# /* :FIXME: improve here */
# define RBIMPL_WARNING_PUSH() /* void */
# define RBIMPL_WARNING_POP() /* void */
# define RBIMPL_WARNING_ERROR(flag) /* void */
# define RBIMPL_WARNING_IGNORED(flag) /* void */
#endif /* _MSC_VER */
/** @endcond */
#endif /* RBIMPL_WARNING_PUSH_H */
include/ruby/internal/module.h 0000644 00000016103 15040330603 0012415 0 ustar 00 #ifndef RBIMPL_MODULE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_MODULE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Creation and modification of Ruby modules.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
/**
* @defgroup class Classes and their hierarchy.
*
* @par Terminology
* - class: same as in Ruby.
* - singleton class: class for a particular object.
* - eigenclass: = singleton class
* - metaclass: class of a class. Metaclass is a kind of singleton class.
* - metametaclass: class of a metaclass.
* - meta^(n)-class: class of a meta^(n-1)-class.
* - attached object: A singleton class knows its unique instance.
* The instance is called the attached object for the singleton class.
* @{
*/
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
* Defines a top-level class.
*
* @param[in] name Name of the class.
* @param[in] super A class from which the new class will derive.
* @exception rb_eTypeError The constant name `name` is already taken but the
* constant is not a class.
* @exception rb_eTypeError The class is already defined but the class can
* not be reopened because its superclass is not
* `super`.
* @exception rb_eArgError `super` is NULL.
* @return The created class.
* @post Top-level constant named `name` refers the returned class.
* @note If a class named `name` is already defined and its superclass is
* `super`, the function just returns the defined class.
* @note The compaction GC does not move classes returned by this
* function.
*
* @internal
*
* There are classes without names, but you can't pass NULL here. You have to
* use other ways to create one.
*/
VALUE rb_define_class(const char *name, VALUE super);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a top-level module.
*
* @param[in] name Name of the module.
* @exception rb_eTypeError The constant name `name` is already taken but the
* constant is not a module.
* @return The created module.
* @post Top-level constant named `name` refers the returned module.
* @note The compaction GC does not move classes returned by this
* function.
*
* @internal
*
* There are modules without names, but you can't pass NULL here. You have to
* use other ways to create one.
*/
VALUE rb_define_module(const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a class under the namespace of `outer`.
*
* @param[out] outer A class which contains the new class.
* @param[in] name Name of the new class
* @param[in] super A class from which the new class will derive.
* 0 means ::rb_cObject.
* @exception rb_eTypeError The constant name `name` is already taken but
* the constant is not a class.
* @exception rb_eTypeError The class is already defined but the class can
* not be reopened because its superclass is not
* `super`.
* @exception rb_eArgError `super` is NULL.
* @return The created class.
* @post `outer::name` refers the returned class.
* @note If a class named `name` is already defined and its superclass
* is `super`, the function just returns the defined class.
* @note The compaction GC does not move classes returned by this
* function.
*/
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a module under the namespace of `outer`.
*
* @param[out] outer A class which contains the new module.
* @param[in] name Name of the new module
* @exception rb_eTypeError The constant name `name` is already taken but
* the constant is not a class.
* @return The created module.
* @post `outer::name` refers the returned module.
* @note The compaction GC does not move classes returned by this
* function.
*/
VALUE rb_define_module_under(VALUE outer, const char *name);
/**
* Includes a module to a class.
*
* @param[out] klass Inclusion destination.
* @param[in] module Inclusion source.
* @exception rb_eArgError Cyclic inclusion.
*
* @internal
*
* :FIXME: @shyouhei suspects this function lacks assertion that the arguments
* being modules... Could silently SEGV if non-module was passed?
*/
void rb_include_module(VALUE klass, VALUE module);
/**
* Extend the object with the module.
*
* @warning This is the same as `Module#extend_object`, not
* `Object#extend`! These two methods are very similar, but not
* identical. The difference is the hook. `Module#extend_object`
* does not invoke `Module#extended`, while `Object#extend` does.
* @param[out] obj Object to extend.
* @param[in] mod Module of extension.
*/
void rb_extend_object(VALUE obj, VALUE mod);
/**
* Identical to rb_include_module(), except it "prepends" the passed module to
* the klass, instead of includes. This affects how `super` resolves. For
* instance:
*
* ```ruby
* class Q; def foo; "<q/>" end end
* module W; def foo; "<w>#{super}</w>" end end
* class E < Q; include W; def foo; "<e>#{super}</e>" end end
* class R < Q; prepend W; def foo; "<r>#{super}</r>" end end
*
* E.new.foo # => "<e><w><q/></w></e>"
* r.new.foo # => "<W><r><q/></r></w>"
* ```
*
* @param[out] klass Target class to modify.
* @param[in] module Module to prepend.
* @exception rb_eArgError Cyclic inclusion.
*/
void rb_prepend_module(VALUE klass, VALUE module);
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_MODULE_H */
include/ruby/internal/error.h 0000644 00000050371 15040330603 0012266 0 ustar 00 #ifndef RBIMPL_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ERROR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Declares ::rb_raise().
*/
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
/**
* @defgroup exception Exception handlings
* @{
*/
/**
* Warning categories. A warning issued using this API can be selectively
* requested / suppressed by the end-users. For instance passing
* `-W:no-deprecated` to the ruby process would suppress those warnings in
* deprecated category.
*
* @warning There is no way to declare a new category (for now).
*/
typedef enum {
/** Category unspecified. */
RB_WARN_CATEGORY_NONE,
/** Warning is for deprecated features. */
RB_WARN_CATEGORY_DEPRECATED,
/** Warning is for experimental features. */
RB_WARN_CATEGORY_EXPERIMENTAL,
RB_WARN_CATEGORY_ALL_BITS = 0x6 /* no RB_WARN_CATEGORY_NONE bit */
} rb_warning_category_t;
/** for rb_readwrite_sys_fail first argument */
enum rb_io_wait_readwrite {RB_IO_WAIT_READABLE, RB_IO_WAIT_WRITABLE};
/** @cond INTERNAL_MACRO */
#define RB_IO_WAIT_READABLE RB_IO_WAIT_READABLE
#define RB_IO_WAIT_WRITABLE RB_IO_WAIT_WRITABLE
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the same as `$!` in Ruby.
*
* @retval RUBY_Qnil Not handling exceptions at the moment.
* @retval otherwise The current exception in the current thread.
* @ingroup exception
*/
VALUE rb_errinfo(void);
/**
* Sets the current exception (`$!`) to the given value.
*
* @param[in] err An instance of ::rb_eException, or ::RUBY_Qnil.
* @exception rb_eTypeError What is given was neither ::rb_eException nor
* ::RUBY_Qnil.
* @note Use rb_raise() instead to raise `err`. This function just
* assigns the given object to the global variable.
* @ingroup exception
*/
void rb_set_errinfo(VALUE err);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Exception entry point. By calling this function the execution of your
* program gets interrupted to "raise" an exception up to the callee entities.
* Programs could "rescue" that exception, or could "ensure" some part of them.
* If nobody cares about such things, the raised exception reaches at the top
* of execution. This yields abnormal end of the process.
*
* @param[in] exc A subclass of ::rb_eException.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception exc The specified exception.
* @note It never returns.
*/
void rb_raise(VALUE exc, const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Raises the unsung "fatal" exception. This is considered severe. Nobody can
* rescue the exception. Once raised, process termination is inevitable.
* However ensure clauses still run, so that resources are properly cleaned up.
*
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @exception rb_eFatal An exception that you cannot rescue.
* @note It never returns.
*/
void rb_fatal(const char *fmt, ...);
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Interpreter panic switch. Immediate process termination without any
* synchronisations shall occur. LOTS of internal states, stack traces, and
* even machine registers are displayed if possible for debugging purposes
* then.
*
* @warning Do not use this API.
* @warning You are not expected to use this API.
* @warning Why not just fix your code instead of calling this API?
* @warning It was a bad idea to expose this API to extension libraries at
* the first place. We just cannot delete it at this point for
* backwards compatibility. That doesn't mean everyone are
* welcomed to call this function at will.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @note It never returns.
*/
void rb_bug(const char *fmt, ...);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
* This is a wrapper of rb_bug() which automatically constructs appropriate
* message from the passed errno.
*
* @param[in] msg Additional message to display.
* @exception err C level errno.
* @note It never returns.
*/
void rb_bug_errno(const char *msg, int err);
RBIMPL_ATTR_NORETURN()
/**
* Converts a C errno into a Ruby exception, then raises it. For instance:
*
* ```CXX
* static VALUE
* foo(VALUE argv)
* {
* const auto cmd = StringValueCStr(argv);
* const auto waitr = system(cmd);
* if (waitr == -1) {
* rb_sys_fail("system(3posix)"); // <-------------- this
* }
* else {
* return INT2FIX(fd);
* }
* }
* ```
*
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing errno.
* @note It never returns.
*/
void rb_sys_fail(const char *msg);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_sys_fail(), except it takes the message in Ruby's String
* instead of C's.
*
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing errno.
* @note It never returns.
*/
void rb_sys_fail_str(VALUE msg);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
/**
* Identical to rb_sys_fail(), except it takes additional module to extend the
* exception object before raising.
*
* @param[in] mod A ::rb_cModule instance.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing errno.
* @note It never returns.
*
* @internal
*
* Does anybody use it?
*/
void rb_mod_sys_fail(VALUE mod, const char *msg);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_mod_sys_fail(), except it takes the message in Ruby's String
* instead of C's.
*
* @param[in] mod A ::rb_cModule instance.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing errno.
* @note It never returns.
*/
void rb_mod_sys_fail_str(VALUE mod, VALUE msg);
RBIMPL_ATTR_NORETURN()
/**
* Raises appropriate exception using the parameters.
*
* In Ruby level there are rb_eEAGAINWaitReadable etc. This function maps the
* given parameter to an appropriate exception class, then raises it.
*
* @param[in] waiting Reason for the IO to wait.
* @param[in] msg Additional message to raise.
* @exception rb_eEAGAINWaitWritable
* @exception rb_eEWOULDBLOCKWaitWritable
* @exception rb_eEINPROGRESSWaitWritable
* @exception rb_eEAGAINWaitReadable
* @exception rb_eEWOULDBLOCKWaitReadable
* @exception rb_eEINPROGRESSWaitReadable
* @exception rb_eSystemCallError
* @note It never returns.
*/
void rb_readwrite_sys_fail(enum rb_io_wait_readwrite waiting, const char *msg);
RBIMPL_ATTR_NORETURN()
/**
* Breaks from a block. Because you are using a CAPI this is not as intuitive
* as it sounds. In order for this function to properly work, make a
* ::rb_block_call_func_t function that calls it internally, and pass that
* function to rb_block_call().
*
* @exception rb_eLocalJumpError Called from outside of a block.
* @note It never returns.
*/
void rb_iter_break(void);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_iter_break(), except it additionally takes the "value" of
* this breakage. It will be the evaluation result of the iterator. This is
* kind of complicated; you cannot see this as a "return from a block"
* behaviour. Take a look at this example:
*
* ```ruby
* def foo(q)
* puts(w = yield(q))
* puts(e = yield(w))
* puts(r = yield(e))
* puts(t = yield(r))
* puts(y = yield(t))
* return "howdy!"
* end
*
* x = foo(0) {|i|
* if i > 2
* break "hello!"
* else
* next i + 1
* end
* }
*
* puts x
* ```
*
* This script outputs 1, 2, 3, and hello. Note that the value passed to break
* becomes the return value of foo method, not the value of yield. This is
* confusing, but can be handy on occasions e.g. when you want to bring a
* local variable out of a block.
*
* @param[in] val The value of the iterator.
* @exception rb_eLocalJumpError Called from outside of a block.
* @note It never returns.
*/
void rb_iter_break_value(VALUE val);
RBIMPL_ATTR_NORETURN()
/**
* Terminates the current execution context. This API is the entry point of a
* "well-mannered" termination sequence. When called from an extension
* library, it raises ::rb_eSystemExit exception. Programs could rescue that
* exception. Can cancel process exit then. Otherwise, that exception results
* in a process termination with the status passed to this function.
*
* @param[in] status Exit status, see also exit(3).
* @exception rb_eSystemExit Exception representing the exit status.
* @note It never returns.
*
* @internal
*
* "When called from an extension library"? You might wonder. In fact there
* are chances for this function to be called from outside of it, for instance
* when dlopen(3) failed. In case it is not possible for this function to
* raise an exception, it does not (silently enters to process cleanup). But
* that is a kind of implementation detail which extension library authors
* should not bother.
*/
void rb_exit(int status);
RBIMPL_ATTR_NORETURN()
/**
* @exception rb_eNotImpError
* @note It never returns.
*/
void rb_notimplement(void);
/**
* Creates an exception object that represents the given C errno.
*
* @param[in] err C level errno.
* @param[in] msg Additional message.
* @retval rb_eSystemCallError An exception for the errno.
*/
VALUE rb_syserr_new(int err, const char * msg);
/**
* Identical to rb_syserr_new(), except it takes the message in Ruby's String
* instead of C's.
*
* @param[in] n C level errno.
* @param[in] arg Additional message.
* @retval rb_eSystemCallError An exception for the errno.
*/
VALUE rb_syserr_new_str(int n, VALUE arg);
RBIMPL_ATTR_NORETURN()
/**
* Raises appropriate exception that represents a C errno.
*
* @param[in] err C level errno.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing `err`.
* @note It never returns.
*/
void rb_syserr_fail(int err, const char *msg);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_syserr_fail(), except it takes the message in Ruby's String
* instead of C's.
*
* @param[in] err C level errno.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing `err`.
* @note It never returns.
*/
void rb_syserr_fail_str(int err, VALUE msg);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_mod_sys_fail(), except it does not depend on C global
* variable errno. Pass it explicitly.
*
* @param[in] mod A ::rb_cModule instance.
* @param[in] err C level errno.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing `err`.
* @note It never returns.
*/
void rb_mod_syserr_fail(VALUE mod, int err, const char *msg);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_mod_syserr_fail(), except it takes the message in Ruby's
* String instead of C's.
*
* @param[in] mod A ::rb_cModule instance.
* @param[in] err C level errno.
* @param[in] msg Additional message to raise.
* @exception rb_eSystemCallError An exception representing `err`.
* @note It never returns.
*/
void rb_mod_syserr_fail_str(VALUE mod, int err, VALUE msg);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_readwrite_sys_fail(), except it does not depend on C global
* variable errno. Pass it explicitly.
*
* @param[in] waiting Reason for the IO to wait.
* @param[in] err C level errno.
* @param[in] msg Additional message to raise.
* @exception rb_eEAGAINWaitWritable
* @exception rb_eEWOULDBLOCKWaitWritable
* @exception rb_eEINPROGRESSWaitWritable
* @exception rb_eEAGAINWaitReadable
* @exception rb_eEWOULDBLOCKWaitReadable
* @exception rb_eEINPROGRESSWaitReadable
* @exception rb_eSystemCallError
* @note It never returns.
*/
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite waiting, int err, const char *msg);
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
* Fails with the given object's type incompatibility to the type.
*
* It seems this function is visible from extension libraries only because
* RTYPEDDATA_TYPE() uses it on RUBY_DEBUG. So you can basically ignore it;
* use some other fine-grained method instead.
*
* @param[in] self The object in question.
* @param[in] t Expected type of the object.
* @exception rb_eTypeError `self` not in type `t`.
* @note It never returns.
* @note The second argument must have been an enum ::ruby_value_type,
* but for historical reasons it remains to be an int (in other
* words we see no benefits fixing this bug).
*/
void rb_unexpected_type(VALUE self, int t);
/**
* @private
*
* This is an implementation detail of #ruby_verbose. Please don't use it
* directly.
*
* @retval Qnil Interpreter is quiet.
* @retval Qfalse Interpreter is kind of chatty.
* @retval otherwise Interpreter is very verbose.
*/
VALUE *rb_ruby_verbose_ptr(void);
/**
* @private
*
* This is an implementation detail of #ruby_debug. Please don't use it
* directly.
*
* @retval Qnil Interpreter not in debug mode.
* @retval Qfalse Interpreter not in debug mode.
* @retval otherwise Interpreter is in debug mode.
*/
VALUE *rb_ruby_debug_ptr(void);
/**
* This variable controls whether the interpreter is in debug mode. Setting
* this to some truthy value is equivalent to passing `-W` flag to the
* interpreter. Setting this to ::Qfalse is equivalent to passing `-W1` flag
* to the interpreter. Setting this to ::Qnil is equivalent to passing `-W0`
* flag to the interpreter.
*
* @retval Qnil Interpreter is quiet.
* @retval Qfalse Interpreter is kind of chatty.
* @retval otherwise Interpreter is very verbose.
*/
#define ruby_verbose (*rb_ruby_verbose_ptr())
/**
* This variable controls whether the interpreter is in debug mode. Setting
* this to some truthy value is equivalent to passing `-d` flag to the
* interpreter.
*
* @retval Qnil Interpreter not in debug mode.
* @retval Qfalse Interpreter not in debug mode.
* @retval otherwise Interpreter is in debug mode.
*/
#define ruby_debug (*rb_ruby_debug_ptr())
/* reports if `-W' specified */
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Issues a warning.
*
* In ruby, warnings these days are tightly coupled with the rb_mWarning
* constant and its `warn` singleton method. This CAPI is just a thin wrapper
* of it; everything passed are formatted like what rb_sprintf() does, then
* passed through to the method. Programs can have their own `def
* Warning.warn` at will to do whatever they want, from ignoring the warnings
* at all to sinking them to some BigQuery data set via a Fluentd cluster. By
* default, the method just emits its passed contents to ::rb_stderr using
* rb_io_write().
*
* @note This function is affected by the `-W` flag.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_warning(const char *fmt, ...);
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_warning(), except it takes additional "category" parameter.
*
* @param[in] cat Name of a known category.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_category_warning(rb_warning_category_t cat, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
* Issues a compile-time warning that happens at `__file__:__line__`. Purpose
* of this function being exposed to CAPI is unclear.
*
* @note This function is affected by the `-W` flag.
* @param[in] file The path corresponding to Ruby level `__FILE__`.
* @param[in] line The number corresponding to Ruby level `__LINE__`.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_compile_warning(const char *file, int line, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Identical to rb_sys_fail(), except it does not raise an exception to render
* a warning instead.
*
* @note This function is affected by the `-W` flag.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_sys_warning(const char *fmt, ...);
/* reports always */
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
* Identical to rb_warning(), except it reports always regardless of runtime
* `-W` flag.
*
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_warn(const char *fmt, ...);
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_category_warning(), except it reports always regardless of
* runtime `-W` flag.
*
* @param[in] cat Category e.g. deprecated.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
* Identical to rb_compile_warning(), except it reports always regardless of
* runtime `-W` flag.
*
* @param[in] file The path corresponding to Ruby level `__FILE__`.
* @param[in] line The number corresponding to Ruby level `__LINE__`.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_compile_warn(const char *file, int line, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((2, 4))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 5)
/**
* Identical to rb_compile_warn(), except it also accepts category.
*
* @param[in] cat Category e.g. deprecated.
* @param[in] file The path corresponding to Ruby level `__FILE__`.
* @param[in] line The number corresponding to Ruby level `__LINE__`.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
*/
void rb_category_compile_warn(rb_warning_category_t cat, const char *file, int line, const char *fmt, ...);
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_ERROR_H */
include/ruby/internal/arithmetic/size_t.h 0000644 00000005524 15040330603 0014563 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_SIZE_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_SIZE_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `size_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/backward/2/long_long.h"
#if defined(__DOXYGEN__)
# /** Converts a C's `size_t` into an instance of ::rb_cInteger. */
# define RB_SIZE2NUM RB_ULONG2NUM
# /** Converts a C's `ssize_t` into an instance of ::rb_cInteger. */
# define RB_SSIZE2NUM RB_LONG2NUM
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define RB_SIZE2NUM RB_ULL2NUM
# define RB_SSIZE2NUM RB_LL2NUM
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define RB_SIZE2NUM RB_ULONG2NUM
# define RB_SSIZE2NUM RB_LONG2NUM
#else
# define RB_SIZE2NUM RB_UINT2NUM
# define RB_SSIZE2NUM RB_INT2NUM
#endif
#if defined(__DOXYGEN__)
# /** Converts an instance of ::rb_cInteger into C's `size_t`. */
# define RB_NUM2SIZE RB_NUM2ULONG
# /** Converts an instance of ::rb_cInteger into C's `ssize_t`. */
# define RB_NUM2SSIZE RB_NUM2LONG
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define RB_NUM2SIZE RB_NUM2ULL
# define RB_NUM2SSIZE RB_NUM2LL
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define RB_NUM2SIZE RB_NUM2ULONG
# define RB_NUM2SSIZE RB_NUM2LONG
#else
# define RB_NUM2SIZE RB_NUM2UINT
# define RB_NUM2SSIZE RB_NUM2INT
#endif
#define NUM2SIZET RB_NUM2SIZE /**< @old{RB_NUM2SIZE} */
#define SIZET2NUM RB_SIZE2NUM /**< @old{RB_SIZE2NUM} */
#define NUM2SSIZET RB_NUM2SSIZE /**< @old{RB_NUM2SSIZE} */
#define SSIZET2NUM RB_SSIZE2NUM /**< @old{RB_SSIZE2NUM} */
#endif /* RBIMPL_ARITHMETIC_SIZE_T_H */
include/ruby/internal/arithmetic/off_t.h 0000644 00000004704 15040330603 0014362 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_OFF_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_OFF_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `off_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/backward/2/long_long.h"
/** Converts a C's `off_t` into an instance of ::rb_cInteger. */
#ifdef OFFT2NUM
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define OFFT2NUM RB_LL2NUM
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define OFFT2NUM RB_LONG2NUM
#else
# define OFFT2NUM RB_INT2NUM
#endif
/** Converts an instance of ::rb_cNumeric into C's `off_t`. */
#ifdef NUM2OFFT
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define NUM2OFFT RB_NUM2LL
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define NUM2OFFT RB_NUM2LONG
#else
# define NUM2OFFT RB_NUM2INT
#endif
/** A rb_sprintf() format prefix to be used for an `off_t` parameter. */
#ifdef PRI_OFFT_PREFIX
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define PRI_OFFT_PREFIX PRI_LL_PREFIX
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define PRI_OFFT_PREFIX PRI_LONG_PREFIX
#else
# define PRI_OFFT_PREFIX PRI_INT_PREFIX
#endif
#endif /* RBIMPL_ARITHMETIC_OFF_T_H */
include/ruby/internal/arithmetic/st_data_t.h 0000644 00000005663 15040330603 0015234 0 ustar 00 #ifndef RBIMPL_ARITHMERIC_ST_DATA_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMERIC_ST_DATA_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `st_data_t` and Ruby's.
*/
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
#include "ruby/st.h"
#define ST2FIX RB_ST2FIX /**< @old{RB_ST2FIX} */
/** @cond INTERNAL_MACRO */
#define RB_ST2FIX RB_ST2FIX
/** @endcond */
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Converts a C's `st_data_t` into an instance of ::rb_cInteger.
*
* @param[in] i The data in question.
* @return A converted result
* @warning THIS CONVERSION LOSES DATA! Be warned.
* @see https://bugs.ruby-lang.org/issues/13877
* @see https://bugs.ruby-lang.org/issues/14218
*
* @internal
*
* This is needed because of hash functions. Hash functions return
* `st_data_t`, which could theoretically be bigger than Fixnums. However
* allocating Bignums for them every time we calculate hash values is just too
* heavy. To avoid penalty we need to ignore some upper bit(s) and stick to
* Fixnums. This function is used for that purpose.
*/
static inline VALUE
RB_ST2FIX(st_data_t i)
{
SIGNED_VALUE x = i;
if (x >= 0) {
x &= RUBY_FIXNUM_MAX;
}
else {
x |= RUBY_FIXNUM_MIN;
}
RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(x));
unsigned long y = RBIMPL_CAST((unsigned long)x);
return RB_LONG2FIX(y);
}
#endif /* RBIMPL_ARITHMETIC_ST_DATA_T_H */
include/ruby/internal/arithmetic/long.h 0000644 00000026273 15040330603 0014231 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_LONG_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `long` and Ruby's.
*
* ### Q&A ###
*
* - Q: Why are INT2FIX etc. here, not in `int.h`?
*
* - A: Because they are in fact handling `long`. It seems someone did not
* understand the difference of `int` and `long` when they designed those
* macros.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/fixnum.h" /* FIXABLE */
#include "ruby/internal/arithmetic/intptr_t.h" /* rb_int2big etc.*/
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h" /* FIXNUM_FLAG */
#include "ruby/internal/value.h"
#include "ruby/assert.h"
#define FIX2LONG RB_FIX2LONG /**< @old{RB_FIX2LONG} */
#define FIX2ULONG RB_FIX2ULONG /**< @old{RB_FIX2ULONG} */
#define INT2FIX RB_INT2FIX /**< @old{RB_INT2FIX} */
#define LONG2FIX RB_INT2FIX /**< @old{RB_INT2FIX} */
#define LONG2NUM RB_LONG2NUM /**< @old{RB_LONG2NUM} */
#define NUM2LONG RB_NUM2LONG /**< @old{RB_NUM2LONG} */
#define NUM2ULONG RB_NUM2ULONG /**< @old{RB_NUM2ULONG} */
#define RB_FIX2LONG rb_fix2long /**< @alias{rb_fix2long} */
#define RB_FIX2ULONG rb_fix2ulong /**< @alias{rb_fix2ulong} */
#define RB_LONG2FIX RB_INT2FIX /**< @alias{RB_INT2FIX} */
#define RB_LONG2NUM rb_long2num_inline /**< @alias{rb_long2num_inline} */
#define RB_NUM2LONG rb_num2long_inline /**< @alias{rb_num2long_inline} */
#define RB_NUM2ULONG rb_num2ulong_inline /**< @alias{rb_num2ulong_inline} */
#define RB_ULONG2NUM rb_ulong2num_inline /**< @alias{rb_ulong2num_inline} */
#define ULONG2NUM RB_ULONG2NUM /**< @old{RB_ULONG2NUM} */
#define rb_fix_new RB_INT2FIX /**< @alias{RB_INT2FIX} */
#define rb_long2int rb_long2int_inline /**< @alias{rb_long2int_inline} */
/** @cond INTERNAL_MACRO */
#define RB_INT2FIX RB_INT2FIX
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
/**
* This is an utility function to raise an ::rb_eRangeError.
*
* @param[in] num A signed value about to overflow.
* @exception rb_eRangeError `num` is out of range of `int`.
*/
void rb_out_of_int(SIGNED_VALUE num);
/**
* Converts an instance of ::rb_cNumeric into C's `long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `long`.
* @return The passed value converted into C's `long`.
*/
long rb_num2long(VALUE num);
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned long`.
* @return The passed value converted into C's `unsigned long`.
*/
unsigned long rb_num2ulong(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Converts a C's `long` into an instance of ::rb_cInteger.
*
* @param[in] i Arbitrary `long` value.
* @return An instance of ::rb_cInteger.
*/
static inline VALUE
RB_INT2FIX(long i)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(i));
/* :NOTE: VALUE can be wider than long. As j being unsigned, 2j+1 is fully
* defined. Also it can be compiled into a single LEA instruction. */
const unsigned long j = i;
const unsigned long k = (j << 1) + RUBY_FIXNUM_FLAG;
const long l = k;
const SIGNED_VALUE m = l; /* Sign extend */
const VALUE n = m;
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(n));
return n;
}
/**
* Checks if `int` can hold the given integer.
*
* @param[in] n Arbitrary `long` value.
* @exception rb_eRangeError `n` is out of range of `int`.
* @return Identical value of type `int`
*/
static inline int
rb_long2int_inline(long n)
{
int i = RBIMPL_CAST((int)n);
if /* constexpr */ (sizeof(long) <= sizeof(int)) {
RBIMPL_ASSUME(i == n);
}
if (i != n)
rb_out_of_int(n);
return i;
}
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
* @private
*
* This is an implementation detail of rb_fix2long(). People don't use it
* directly.
*
* @param[in] x A Fixnum.
* @return Identical value of type `long`
* @pre Must not pass anything other than a Fixnum.
*/
static inline long
rbimpl_fix2long_by_idiv(VALUE x)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
/* :NOTE: VALUE can be wider than long. (x-1)/2 never overflows because
* RB_FIXNUM_P(x) holds. Also it has no portability issue like y>>1
* below. */
const SIGNED_VALUE y = x - RUBY_FIXNUM_FLAG;
const SIGNED_VALUE z = y / 2;
const long w = RBIMPL_CAST((long)z);
RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
return w;
}
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
* @private
*
* This is an implementation detail of rb_fix2long(). People don't use it
* directly.
*
* @param[in] x A Fixnum.
* @return Identical value of type `long`
* @pre Must not pass anything other than a Fixnum.
*/
static inline long
rbimpl_fix2long_by_shift(VALUE x)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
/* :NOTE: VALUE can be wider than long. If right shift is arithmetic, this
* is noticeably faster than above. */
const SIGNED_VALUE y = x;
const SIGNED_VALUE z = y >> 1;
const long w = RBIMPL_CAST((long)z);
RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
return w;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
/**
* @private
*
* This is an implementation detail of rb_fix2long(). People don't use it
* directly.
*
* @retval true This C compiler's right shift operator is arithmetic.
* @retval false This C compiler's right shift operator is logical.
*/
static inline bool
rbimpl_right_shift_is_arithmetic_p(void)
{
return (-1 >> 1) == -1;
}
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
* Converts a Fixnum into C's `long`.
*
* @param[in] x Some Fixnum.
* @pre Must not pass anything other than a Fixnum.
* @return The passed value converted into C's `long`.
*/
static inline long
rb_fix2long(VALUE x)
{
if /* constexpr */ (rbimpl_right_shift_is_arithmetic_p()) {
return rbimpl_fix2long_by_shift(x);
}
else {
return rbimpl_fix2long_by_idiv(x);
}
}
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
* Converts a Fixnum into C's `unsigned long`.
*
* @param[in] x Some Fixnum.
* @pre Must not pass anything other than a Fixnum.
* @return The passed value converted into C's `unsigned long`.
* @note Negative fixnums will be converted into large unsigned longs.
*/
static inline unsigned long
rb_fix2ulong(VALUE x)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
return rb_fix2long(x);
}
/**
* Converts an instance of ::rb_cNumeric into C's `long`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `long`.
* @return The passed value converted into C's `long`.
*/
static inline long
rb_num2long_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return RB_FIX2LONG(x);
else
return rb_num2long(x);
}
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned long`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `unsigned long`.
* @return The passed value converted into C's `unsigned long`.
*
* @internal
*
* This (negative fixnum would become a large unsigned long while negative
* bignum is an exception) has been THE behaviour of NUM2ULONG since the
* beginning. It is strange, but we can no longer change how it works at this
* moment. We have to get by with it.
*
* @see https://bugs.ruby-lang.org/issues/9089
*/
static inline unsigned long
rb_num2ulong_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return RB_FIX2ULONG(x);
else
return rb_num2ulong(x);
}
/**
* Converts a C's `long` into an instance of ::rb_cInteger.
*
* @param[in] v Arbitrary `long` value.
* @return An instance of ::rb_cInteger.
*/
static inline VALUE
rb_long2num_inline(long v)
{
if (RB_FIXABLE(v))
return RB_LONG2FIX(v);
else
return rb_int2big(v);
}
/**
* Converts a C's `unsigned long` into an instance of ::rb_cInteger.
*
* @param[in] v Arbitrary `unsigned long` value.
* @return An instance of ::rb_cInteger.
*/
static inline VALUE
rb_ulong2num_inline(unsigned long v)
{
if (RB_POSFIXABLE(v))
return RB_LONG2FIX(v);
else
return rb_uint2big(v);
}
/**
* @cond INTERNAL_MACRO
*
* Following overload is necessary because sometimes INT2FIX is used as a enum
* value (e.g. `enum { FOO = INT2FIX(0) };`). THIS IS NG in theory because a
* VALUE does not fit into an enum (which must be a signed int). But we cannot
* break existing codes.
*/
#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
# /* C++ can write constexpr as enum values. */
#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# undef INT2FIX
# define INT2FIX(i) (RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG)
#else
# undef INT2FIX
# define INT2FIX(i) \
__builtin_choose_expr( \
__builtin_constant_p(i), \
RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG, \
RB_INT2FIX(i))
#endif
/** @endcond */
#endif /* RBIMPL_ARITHMETIC_LONG_H */
include/ruby/internal/arithmetic/mode_t.h 0000644 00000003546 15040330604 0014540 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_MODE_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_MODE_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `mode_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"
/** Converts a C's `mode_t` into an instance of ::rb_cInteger. */
#ifndef NUM2MODET
# define NUM2MODET RB_NUM2INT
#endif
/** Converts an instance of ::rb_cNumeric into C's `mode_t`. */
#ifndef MODET2NUM
# define MODET2NUM RB_INT2NUM
#endif
/** A rb_sprintf() format prefix to be used for a `mode_t` parameter. */
#ifndef PRI_MODET_PREFIX
# define PRI_MODET_PREFIX PRI_INT_PREFIX
#endif
#endif /* RBIMPL_ARITHMETIC_MODE_T_H */
include/ruby/internal/arithmetic/char.h 0000644 00000006453 15040330604 0014206 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_CHAR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_CHAR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `char` and Ruby's.
*/
#include "ruby/internal/arithmetic/int.h" /* NUM2INT is here, but */
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here.*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/value_type.h"
#define RB_NUM2CHR rb_num2char_inline /**< @alias{rb_num2char_inline} */
#define NUM2CHR RB_NUM2CHR /**< @old{RB_NUM2CHR} */
#define CHR2FIX RB_CHR2FIX /**< @old{RB_CHR2FIX} */
/** @cond INTERNAL_MACRO */
#define RB_CHR2FIX RB_CHR2FIX
/** @endcond */
RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Converts a C's `unsigned char` into an instance of ::rb_cInteger.
*
* @param[in] c Arbitrary `unsigned char` value.
* @return An instance of ::rb_cInteger.
*
* @internal
*
* Nobody explicitly states this but in Ruby, a char means an unsigned integer
* value of range 0..255. This is a general principle. AFAIK there is no
* single line of code where char is signed.
*/
static inline VALUE
RB_CHR2FIX(unsigned char c)
{
return RB_INT2FIX(c);
}
/**
* Converts an instance of ::rb_cNumeric into C's `char`. At the same time it
* accepts a String of more than one character, and returns its first byte. In
* the early days there was a Ruby level "character" literal `?c`, which
* roughly worked this way.
*
* @param[in] x Either a string or a numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `unsigned int`.
* @return The passed value converted into C's `char`.
*/
static inline char
rb_num2char_inline(VALUE x)
{
if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
return RSTRING_PTR(x)[0];
else
return RBIMPL_CAST((char)RB_NUM2INT(x));
}
#endif /* RBIMPL_ARITHMETIC_CHAR_H */
include/ruby/internal/arithmetic/intptr_t.h 0000644 00000005421 15040330604 0015126 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_INTPTR_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_INTPTR_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `intptr_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"
#define rb_int_new rb_int2inum /**< @alias{rb_int2inum} */
#define rb_uint_new rb_uint2inum /**< @alias{rb_uint2inum} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts a C's `intptr_t` into an instance of ::rb_cInteger.
*
* @param[in] i Arbitrary `intptr_t` value.
* @return An instance of ::rb_cInteger.
* @note This function always allocates Bignums, even if the given number
* is small enough to fit into a Fixnum.
*/
VALUE rb_int2big(intptr_t i);
/**
* Converts a C's `intptr_t` into an instance of ::rb_cInteger.
*
* @param[in] i Arbitrary `intptr_t` value.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_int2inum(intptr_t i);
/**
* Converts a C's `intptr_t` into an instance of ::rb_cInteger.
*
* @param[in] i Arbitrary `intptr_t` value.
* @return An instance of ::rb_cInteger.
* @note This function always allocates Bignums, even if the given number
* is small enough to fit into a Fixnum.
*/
VALUE rb_uint2big(uintptr_t i);
/**
* Converts a C's `uintptr_t` into an instance of ::rb_cInteger.
*
* @param[in] i Arbitrary `uintptr_t` value.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_uint2inum(uintptr_t i);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_ARITHMETIC_INTPTR_T_H */
include/ruby/internal/arithmetic/fixnum.h 0000644 00000005573 15040330604 0014601 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_FIXNUM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_FIXNUM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Handling of integers formerly known as Fixnums.
*/
#include "ruby/backward/2/limits.h"
#define FIXABLE RB_FIXABLE /**< @old{RB_FIXABLE} */
#define FIXNUM_MAX RUBY_FIXNUM_MAX /**< @old{RUBY_FIXNUM_MAX} */
#define FIXNUM_MIN RUBY_FIXNUM_MIN /**< @old{RUBY_FIXNUM_MIN} */
#define NEGFIXABLE RB_NEGFIXABLE /**< @old{RB_NEGFIXABLE} */
#define POSFIXABLE RB_POSFIXABLE /**< @old{RB_POSFIXABLE} */
/**
* Checks if the passed value is in range of fixnum, assuming it is a positive
* number. Can sometimes be useful for C's unsigned integer types.
*
* @internal
*
* FIXABLE can be applied to anything, from double to intmax_t. The problem is
* double. On a 64bit system RUBY_FIXNUM_MAX is 4,611,686,018,427,387,903,
* which is not representable by a double. The nearest value that a double can
* represent is 4,611,686,018,427,387,904, which is not fixable. The
* seemingly-strange "< FIXNUM_MAX + 1" expression below is due to this.
*/
#define RB_POSFIXABLE(_) ((_) < RUBY_FIXNUM_MAX + 1)
/**
* Checks if the passed value is in range of fixnum, assuming it is a negative
* number. This is an implementation of #RB_FIXABLE. Rarely used stand alone.
*/
#define RB_NEGFIXABLE(_) ((_) >= RUBY_FIXNUM_MIN)
/** Checks if the passed value is in range of fixnum */
#define RB_FIXABLE(_) (RB_POSFIXABLE(_) && RB_NEGFIXABLE(_))
/** Maximum possible value that a fixnum can represent. */
#define RUBY_FIXNUM_MAX (LONG_MAX / 2)
/** Minimum possible value that a fixnum can represent. */
#define RUBY_FIXNUM_MIN (LONG_MIN / 2)
#endif /* RBIMPL_ARITHMETIC_FIXNUM_H */
include/ruby/internal/arithmetic/uid_t.h 0000644 00000003536 15040330604 0014374 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_UID_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_UID_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `uid_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"
/** Converts a C's `uid_t` into an instance of ::rb_cInteger. */
#ifndef UIDT2NUM
# define UIDT2NUM RB_LONG2NUM
#endif
/** Converts an instance of ::rb_cNumeric into C's `uid_t`. */
#ifndef NUM2UIDT
# define NUM2UIDT RB_NUM2LONG
#endif
/** A rb_sprintf() format prefix to be used for a `uid_t` parameter. */
#ifndef PRI_UIDT_PREFIX
# define PRI_UIDT_PREFIX PRI_LONG_PREFIX
#endif
#endif /* RBIMPL_ARITHMETIC_UID_T_H */
include/ruby/internal/arithmetic/gid_t.h 0000644 00000003536 15040330604 0014356 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_GID_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_GID_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `gid_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"
/** Converts a C's `gid_t` into an instance of ::rb_cInteger. */
#ifndef GIDT2NUM
# define GIDT2NUM RB_LONG2NUM
#endif
/** Converts an instance of ::rb_cNumeric into C's `gid_t`. */
#ifndef NUM2GIDT
# define NUM2GIDT RB_NUM2LONG
#endif
/** A rb_sprintf() format prefix to be used for a `gid_t` parameter. */
#ifndef PRI_GIDT_PREFIX
# define PRI_GIDT_PREFIX PRI_LONG_PREFIX
#endif
#endif /* RBIMPL_ARITHMETIC_GID_T_H */
include/ruby/internal/arithmetic/long_long.h 0000644 00000011463 15040330604 0015244 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_LONG_LONG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_LONG_LONG_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `long long` and Ruby's.
*/
#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/backward/2/long_long.h"
#define RB_LL2NUM rb_ll2num_inline /**< @alias{rb_ll2num_inline} */
#define RB_ULL2NUM rb_ull2num_inline /**< @alias{rb_ull2num_inline} */
#define LL2NUM RB_LL2NUM /**< @old{RB_LL2NUM} */
#define ULL2NUM RB_ULL2NUM /**< @old{RB_ULL2NUM} */
#define RB_NUM2LL rb_num2ll_inline /**< @alias{rb_num2ll_inline} */
#define RB_NUM2ULL rb_num2ull_inline /**< @alias{rb_num2ull_inline} */
#define NUM2LL RB_NUM2LL /**< @old{RB_NUM2LL} */
#define NUM2ULL RB_NUM2ULL /**< @old{RB_NUM2ULL} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts a C's `long long` into an instance of ::rb_cInteger.
*
* @param[in] num Arbitrary `long long` value.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_ll2inum(LONG_LONG num);
/**
* Converts a C's `unsigned long long` into an instance of ::rb_cInteger.
*
* @param[in] num Arbitrary `unsigned long long` value.
* @return An instance of ::rb_cInteger.
*/
VALUE rb_ull2inum(unsigned LONG_LONG num);
/**
* Converts an instance of ::rb_cNumeric into C's `long long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `long long`.
* @return The passed value converted into C's `long long`.
*/
LONG_LONG rb_num2ll(VALUE num);
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned long long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned long long`.
* @return The passed value converted into C's `unsigned long long`.
*/
unsigned LONG_LONG rb_num2ull(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()
/**
* Converts a C's `long long` into an instance of ::rb_cInteger.
*
* @param[in] n Arbitrary `long long` value.
* @return An instance of ::rb_cInteger
*/
static inline VALUE
rb_ll2num_inline(LONG_LONG n)
{
if (FIXABLE(n)) return LONG2FIX((long)n);
return rb_ll2inum(n);
}
/**
* Converts a C's `unsigned long long` into an instance of ::rb_cInteger.
*
* @param[in] n Arbitrary `unsigned long long` value.
* @return An instance of ::rb_cInteger
*/
static inline VALUE
rb_ull2num_inline(unsigned LONG_LONG n)
{
if (POSFIXABLE(n)) return LONG2FIX((long)n);
return rb_ull2inum(n);
}
/**
* Converts an instance of ::rb_cNumeric into C's `long long`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `long long`.
* @return The passed value converted into C's `long long`.
*/
static inline LONG_LONG
rb_num2ll_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return RB_FIX2LONG(x);
else
return rb_num2ll(x);
}
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned long long`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `unsigned long long`.
* @return The passed value converted into C's `unsigned long long`.
*/
static inline unsigned LONG_LONG
rb_num2ull_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return RB_FIX2LONG(x);
else
return rb_num2ull(x);
}
#endif /* RBIMPL_ARITHMETIC_LONG_LONG_H */
include/ruby/internal/arithmetic/short.h 0000644 00000010523 15040330604 0014421 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_SHORT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_SHORT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `short` and Ruby's.
*
* Shyouhei wonders: why there is no SHORT2NUM, given there are both
* #USHORT2NUM and #CHR2FIX?
*/
#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#define RB_NUM2SHORT rb_num2short_inline /**< @alias{rb_num2short_inline} */
#define RB_NUM2USHORT rb_num2ushort /**< @alias{rb_num2ushort} */
#define NUM2SHORT RB_NUM2SHORT /**< @old{RB_NUM2SHORT} */
#define NUM2USHORT RB_NUM2USHORT /**< @old{RB_NUM2USHORT} */
#define USHORT2NUM RB_INT2FIX /**< @old{RB_INT2FIX} */
#define RB_FIX2SHORT rb_fix2short /**< @alias{rb_fix2ushort} */
#define FIX2SHORT RB_FIX2SHORT /**< @old{RB_FIX2SHORT} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts an instance of ::rb_cNumeric into C's `short`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `short`.
* @return The passed value converted into C's `short`.
*/
short rb_num2short(VALUE num);
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned short`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned short`.
* @return The passed value converted into C's `unsigned short`.
*/
unsigned short rb_num2ushort(VALUE num);
/**
* Identical to rb_num2short().
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `short`.
* @return The passed value converted into C's `short`.
*
* @internal
*
* This function seems to be a complete waste of disk space. @shyouhei has no
* idea why this is a different thing from rb_num2short().
*/
short rb_fix2short(VALUE num);
/**
* Identical to rb_num2ushort().
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned short`.
* @return The passed value converted into C's `unsigned short`.
*
* @internal
*
* This function seems to be a complete waste of disk space. @shyouhei has no
* idea why this is a different thing from rb_num2ushort().
*/
unsigned short rb_fix2ushort(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()
/**
* Identical to rb_num2short().
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `short`.
* @return The passed value converted into C's `short`.
*
* @internal
*
* This function seems to be a complete waste of time. @shyouhei has no idea
* why this is a different thing from rb_num2short().
*/
static inline short
rb_num2short_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return rb_fix2short(x);
else
return rb_num2short(x);
}
#endif /* RBIMPL_ARITHMETIC_SHORT_H */
include/ruby/internal/arithmetic/double.h 0000644 00000005366 15040330604 0014545 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_DOUBLE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_DOUBLE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `double` and Ruby's.
*/
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#define NUM2DBL rb_num2dbl /**< @old{rb_num2dbl} */
#define RFLOAT_VALUE rb_float_value /**< @old{rb_float_value} */
#define DBL2NUM rb_float_new /**< @old{rb_float_new} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts an instance of ::rb_cNumeric into C's `double`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @return The passed value converted into C's `double`.
*/
double rb_num2dbl(VALUE num);
RBIMPL_ATTR_PURE()
/**
* Extracts its double value from an instance of ::rb_cFloat.
*
* @param[in] num An instance of ::rb_cFloat.
* @pre Must not pass anything other than a Fixnum.
* @return The passed value converted into C's `double`.
*/
double rb_float_value(VALUE num);
/**
* Converts a C's `double` into an instance of ::rb_cFloat.
*
* @param[in] d Arbitrary `double` value.
* @return An instance of ::rb_cFloat.
*/
VALUE rb_float_new(double d);
/**
* Identical to rb_float_new(), except it does not generate Flonums.
*
* @param[in] d Arbitrary `double` value.
* @return An instance of ::rb_cFloat.
*
* @internal
*
* @shyouhei has no idea why it is here.
*/
VALUE rb_float_new_in_heap(double d);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_ARITHMETIC_DOUBLE_H */
include/ruby/internal/arithmetic/pid_t.h 0000644 00000003536 15040330605 0014370 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_PID_T_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_PID_T_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `pid_t` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"
/** Converts a C's `pid_t` into an instance of ::rb_cInteger. */
#ifndef PIDT2NUM
# define PIDT2NUM RB_LONG2NUM
#endif
/** Converts an instance of ::rb_cNumeric into C's `pid_t`. */
#ifndef NUM2PIDT
# define NUM2PIDT RB_NUM2LONG
#endif
/** A rb_sprintf() format prefix to be used for a `pid_t` parameter. */
#ifndef PRI_PIDT_PREFIX
# define PRI_PIDT_PREFIX PRI_LONG_PREFIX
#endif
#endif /* RBIMPL_ARITHMETIC_PID_T_H */
include/ruby/internal/arithmetic/int.h 0000644 00000020062 15040330605 0014054 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_INT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_INT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Arithmetic conversion between C's `int` and Ruby's.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/intptr_t.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/internal/warning_push.h"
#include "ruby/assert.h"
#define RB_INT2NUM rb_int2num_inline /**< @alias{rb_int2num_inline} */
#define RB_NUM2INT rb_num2int_inline /**< @alias{rb_num2int_inline} */
#define RB_UINT2NUM rb_uint2num_inline /**< @alias{rb_uint2num_inline} */
#define FIX2INT RB_FIX2INT /**< @old{RB_FIX2INT} */
#define FIX2UINT RB_FIX2UINT /**< @old{RB_FIX2UINT} */
#define INT2NUM RB_INT2NUM /**< @old{RB_INT2NUM} */
#define NUM2INT RB_NUM2INT /**< @old{RB_NUM2INT} */
#define NUM2UINT RB_NUM2UINT /**< @old{RB_NUM2UINT} */
#define UINT2NUM RB_UINT2NUM /**< @old{RB_UINT2NUM} */
/** @cond INTERNAL_MACRO */
#define RB_FIX2INT RB_FIX2INT
#define RB_NUM2UINT RB_NUM2UINT
#define RB_FIX2UINT RB_FIX2UINT
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts an instance of ::rb_cNumeric into C's `long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `int`.
* @return The passed value converted into C's `long`.
*
* @internal
*
* Yes, the API is really strange. It returns `long`, but raises when the
* value is out of `int`. This seems to be due to the fact that Matz favoured
* K&R before, and his machine at that moment was an ILP32 architecture.
*/
long rb_num2int(VALUE num);
/**
* Identical to rb_num2int().
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `int`.
* @return The passed value converted into C's `long`.
*
* @internal
*
* This function seems to be a complete waste of disk space. @shyouhei has no
* idea why this is a different thing from rb_num2short().
*/
long rb_fix2int(VALUE num);
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned long`.
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned int`.
* @return The passed value converted into C's `unsigned long`.
*
* @internal
*
* Yes, the API is really strange. It returns `unsigned long`, but raises when
* the value is out of `unsigned int`. This seems to be due to the fact that
* Matz favoured K&R before, and his machine at that moment was an ILP32
* architecture.
*/
unsigned long rb_num2uint(VALUE num);
/**
* Identical to rb_num2uint().
*
* @param[in] num Something numeric.
* @exception rb_eTypeError `num` is not a numeric.
* @exception rb_eRangeError `num` is out of range of `unsigned int`.
* @return The passed value converted into C's `unsigned long`.
*
* @internal
*
* This function seems to be a complete waste of disk space. @shyouhei has no
* idea why this is a different thing from rb_num2short().
*/
unsigned long rb_fix2uint(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Converts a Fixnum into C's `int`.
*
* @param[in] x Some Fixnum.
* @pre Must not pass anything other than a Fixnum.
* @return The passed value converted into C's `int`.
*/
static inline int
RB_FIX2INT(VALUE x)
{
/* "FIX2INT raises a TypeError if passed nil", says rubyspec. Not sure if
* that is a desired behaviour but just preserve backwards compatilibily.
*/
#if 0
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
#endif
long ret;
if /* constexpr */ (sizeof(int) < sizeof(long)) {
ret = rb_fix2int(x);
}
else {
ret = RB_FIX2LONG(x);
}
return RBIMPL_CAST((int)ret);
}
/**
* Converts an instance of ::rb_cNumeric into C's `int`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `int`.
* @return The passed value converted into C's `int`.
*/
static inline int
rb_num2int_inline(VALUE x)
{
long ret;
if /* constexpr */ (sizeof(int) == sizeof(long)) {
ret = RB_NUM2LONG(x);
}
else if (RB_FIXNUM_P(x)) {
ret = rb_fix2int(x);
}
else {
ret = rb_num2int(x);
}
return RBIMPL_CAST((int)ret);
}
/**
* Converts an instance of ::rb_cNumeric into C's `unsigned int`.
*
* @param[in] x Something numeric.
* @exception rb_eTypeError `x` is not a numeric.
* @exception rb_eRangeError `x` is out of range of `unsigned int`.
* @return The passed value converted into C's `unsigned int`.
*/
RBIMPL_ATTR_ARTIFICIAL()
static inline unsigned int
RB_NUM2UINT(VALUE x)
{
unsigned long ret;
if /* constexpr */ (sizeof(int) < sizeof(long)) {
ret = rb_num2uint(x);
}
else {
ret = RB_NUM2ULONG(x);
}
return RBIMPL_CAST((unsigned int)ret);
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Converts a Fixnum into C's `int`.
*
* @param[in] x Some Fixnum.
* @pre Must not pass anything other than a Fixnum.
* @return The passed value converted into C's `int`.
*/
static inline unsigned int
RB_FIX2UINT(VALUE x)
{
#if 0 /* Ditto for RB_FIX2INT. */
RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
#endif
unsigned long ret;
if /* constexpr */ (sizeof(int) < sizeof(long)) {
ret = rb_fix2uint(x);
}
else {
ret = RB_FIX2ULONG(x);
}
return RBIMPL_CAST((unsigned int)ret);
}
RBIMPL_WARNING_PUSH()
#if RBIMPL_COMPILER_IS(GCC)
RBIMPL_WARNING_IGNORED(-Wtype-limits) /* We can ignore them here. */
#elif RBIMPL_HAS_WARNING("-Wtautological-constant-out-of-range-compare")
RBIMPL_WARNING_IGNORED(-Wtautological-constant-out-of-range-compare)
#endif
/**
* Converts a C's `int` into an instance of ::rb_cInteger.
*
* @param[in] v Arbitrary `int` value.
* @return An instance of ::rb_cInteger.
*/
static inline VALUE
rb_int2num_inline(int v)
{
if (RB_FIXABLE(v))
return RB_INT2FIX(v);
else
return rb_int2big(v);
}
/**
* Converts a C's `unsigned int` into an instance of ::rb_cInteger.
*
* @param[in] v Arbitrary `unsigned int` value.
* @return An instance of ::rb_cInteger.
*/
static inline VALUE
rb_uint2num_inline(unsigned int v)
{
if (RB_POSFIXABLE(v))
return RB_LONG2FIX(v);
else
return rb_uint2big(v);
}
RBIMPL_WARNING_POP()
#endif /* RBIMPL_ARITHMETIC_INT_H */
include/ruby/internal/scan_args.h 0000644 00000044751 15040330605 0013104 0 ustar 00 #ifndef RBIMPL_SCAN_ARGS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SCAN_ARGS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Compile-time static implementation of ::rb_scan_args().
*
* This is a beast. It statically analyses the argument spec string, and
* expands the assignment of variables into dedicated codes.
*/
#include "ruby/assert.h"
#include "ruby/internal/attr/diagnose_if.h"
#include "ruby/internal/attr/error.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/config.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/intern/array.h" /* rb_ary_new_from_values */
#include "ruby/internal/intern/error.h" /* rb_error_arity */
#include "ruby/internal/intern/hash.h" /* rb_hash_dup */
#include "ruby/internal/intern/proc.h" /* rb_block_proc */
#include "ruby/internal/iterator.h" /* rb_block_given_p / rb_keyword_given_p */
#include "ruby/internal/static_assert.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
/**
* @name Possible values that you should pass to rb_scan_args_kw().
* @{
*/
/** Same behaviour as rb_scan_args(). */
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0
/** The final argument should be a hash treated as keywords.*/
#define RB_SCAN_ARGS_KEYWORDS 1
/**
* Treat a final argument as keywords if it is a hash, and not as keywords
* otherwise.
*/
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3
/** @} */
/**
* @name Possible values that you should pass to rb_funcallv_kw().
* @{
*/
/** Do not pass keywords. */
#define RB_NO_KEYWORDS 0
/** Pass keywords, final argument should be a hash of keywords. */
#define RB_PASS_KEYWORDS 1
/**
* Pass keywords if current method is called with keywords, useful for argument
* delegation
*/
#define RB_PASS_CALLED_KEYWORDS rb_keyword_given_p()
/** @} */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((2, 3))
/**
* Retrieves argument from argc and argv to given ::VALUE references according
* to the format string. The format can be described in ABNF as follows:
*
* ```
* scan-arg-spec := param-arg-spec [keyword-arg-spec] [block-arg-spec]
*
* param-arg-spec := pre-arg-spec [post-arg-spec] / post-arg-spec /
* pre-opt-post-arg-spec
* pre-arg-spec := num-of-leading-mandatory-args
* [num-of-optional-args]
* post-arg-spec := sym-for-variable-length-args
* [num-of-trailing-mandatory-args]
* pre-opt-post-arg-spec := num-of-leading-mandatory-args num-of-optional-args
* num-of-trailing-mandatory-args
* keyword-arg-spec := sym-for-keyword-arg
* block-arg-spec := sym-for-block-arg
*
* num-of-leading-mandatory-args := DIGIT ; The number of leading mandatory
* ; arguments
* num-of-optional-args := DIGIT ; The number of optional arguments
* sym-for-variable-length-args := "*" ; Indicates that variable length
* ; arguments are captured as a ruby
* ; array
* num-of-trailing-mandatory-args := DIGIT ; The number of trailing mandatory
* ; arguments
* sym-for-keyword-arg := ":" ; Indicates that keyword argument
* ; captured as a hash.
* ; If keyword arguments are not
* ; provided, returns nil.
* sym-for-block-arg := "&" ; Indicates that an iterator block
* ; should be captured if given
* ```
*
* For example, "12" means that the method requires at least one argument, and
* at most receives three (1+2) arguments. So, the format string must be
* followed by three variable references, which are to be assigned to captured
* arguments. For omitted arguments, variables are set to ::RUBY_Qnil. `NULL`
* can be put in place of a variable reference, which means the corresponding
* captured argument(s) should be just dropped.
*
* The number of given arguments, excluding an option hash or iterator block,
* is returned.
*
* @param[in] argc Length of `argv`.
* @param[in] argv Pointer to the arguments to parse.
* @param[in] fmt Format, in the language described above.
* @param[out] ... Variables to fill in.
* @exception rb_eFatal Malformed `fmt`.
* @exception rb_eArgError Arity mismatch.
* @return Actually parsed number of given arguments.
* @post Each values passed to `argv` is filled into the variadic
* arguments, according to the format.
*/
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((3, 4))
/**
* Identical to rb_scan_args(), except it also accepts `kw_splat`.
*
* @param[in] kw_splat How to understand the keyword arguments.
* - RB_SCAN_ARGS_PASS_CALLED_KEYWORDS: Same behaviour as rb_scan_args().
* - RB_SCAN_ARGS_KEYWORDS: The final argument is a kwarg.
* - RB_SCAN_ARGS_LAST_HASH_KEYWORDS: The final argument is a kwarg, iff it
* is a hash.
* @param[in] argc Length of `argv`.
* @param[in] argv Pointer to the arguments to parse.
* @param[in] fmt Format, in the language described above.
* @param[out] ... Variables to fill in.
* @exception rb_eFatal Malformed `fmt`.
* @exception rb_eArgError Arity mismatch.
* @return Actually parsed number of given arguments.
* @post Each values passed to `argv` is filled into the variadic
* arguments, according to the format.
*/
int rb_scan_args_kw(int kw_splat, int argc, const VALUE *argv, const char *fmt, ...);
RBIMPL_ATTR_ERROR(("bad scan arg format"))
/**
* @private
*
* This is an implementation detail of rb_scan_args(). People don't use it
* directly.
*/
void rb_scan_args_bad_format(const char*);
RBIMPL_ATTR_ERROR(("variable argument length doesn't match"))
/**
* @private
*
* This is an implementation detail of rb_scan_args(). People don't use it
* directly.
*/
void rb_scan_args_length_mismatch(const char*,int);
RBIMPL_SYMBOL_EXPORT_END()
/** @cond INTERNAL_MACRO */
/* If we could use constexpr the following macros could be inline functions
* ... but sadly we cannot. */
#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)
#define rb_scan_args_count_end(fmt, ofs, vari) \
((fmt)[ofs] ? -1 : (vari))
#define rb_scan_args_count_block(fmt, ofs, vari) \
((fmt)[ofs]!='&' ? \
rb_scan_args_count_end(fmt, ofs, vari) : \
rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_hash(fmt, ofs, vari) \
((fmt)[ofs]!=':' ? \
rb_scan_args_count_block(fmt, ofs, vari) : \
rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_trail(fmt, ofs, vari) \
(!rb_scan_args_isdigit((fmt)[ofs]) ? \
rb_scan_args_count_hash(fmt, ofs, vari) : \
rb_scan_args_count_hash(fmt, (ofs)+1, (vari)+((fmt)[ofs]-'0')))
#define rb_scan_args_count_var(fmt, ofs, vari) \
((fmt)[ofs]!='*' ? \
rb_scan_args_count_trail(fmt, ofs, vari) : \
rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))
#define rb_scan_args_count_opt(fmt, ofs, vari) \
(!rb_scan_args_isdigit((fmt)[ofs]) ? \
rb_scan_args_count_var(fmt, ofs, vari) : \
rb_scan_args_count_var(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
#define rb_scan_args_count_lead(fmt, ofs, vari) \
(!rb_scan_args_isdigit((fmt)[ofs]) ? \
rb_scan_args_count_var(fmt, ofs, vari) : \
rb_scan_args_count_opt(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)
#if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
# /* Assertions done in the attribute. */
# define rb_scan_args_verify(fmt, varc) RBIMPL_ASSERT_NOTHING
#else
# /* At one sight it _seems_ the expressions below could be written using
# * static assertions. The reality is no, they don't. Because fmt is a
# * string literal, any operations against fmt cannot produce the "integer
# * constant expression"s, as defined in ISO/IEC 9899:2018 section 6.6
# * paragraph #6. Static assertions need such integer constant expressions as
# * defined in ISO/IEC 9899:2018 section 6.7.10 paragraph #3.
# *
# * GCC nonetheless constant-folds this into a no-op, though. */
# define rb_scan_args_verify(fmt, varc) \
(sizeof(char[1-2*(rb_scan_args_count(fmt)<0)])!=1 ? \
rb_scan_args_bad_format(fmt) : \
sizeof(char[1-2*(rb_scan_args_count(fmt)!=(varc))])!=1 ? \
rb_scan_args_length_mismatch(fmt, varc) : \
RBIMPL_ASSERT_NOTHING)
#endif
static inline bool
rb_scan_args_keyword_p(int kw_flag, VALUE last)
{
switch (kw_flag) {
case RB_SCAN_ARGS_PASS_CALLED_KEYWORDS:
return !! rb_keyword_given_p();
case RB_SCAN_ARGS_KEYWORDS:
return true;
case RB_SCAN_ARGS_LAST_HASH_KEYWORDS:
return RB_TYPE_P(last, T_HASH);
default:
return false;
}
}
RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_lead_p(const char *fmt)
{
return rb_scan_args_isdigit(fmt[0]);
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_lead(const char *fmt)
{
return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
}
RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_opt_p(const char *fmt)
{
return (rb_scan_args_lead_p(fmt) && rb_scan_args_isdigit(fmt[1]));
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_opt(const char *fmt)
{
return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_var_idx(const char *fmt)
{
return (!rb_scan_args_lead_p(fmt) ? 0 : !rb_scan_args_isdigit(fmt[1]) ? 1 : 2);
}
RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_var(const char *fmt)
{
return (fmt[rb_scan_args_var_idx(fmt)]=='*');
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_trail_idx(const char *fmt)
{
const int idx = rb_scan_args_var_idx(fmt);
return idx+(fmt[idx]=='*');
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_trail(const char *fmt)
{
const int idx = rb_scan_args_trail_idx(fmt);
return (rb_scan_args_isdigit(fmt[idx]) ? fmt[idx]-'0' : 0);
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_hash_idx(const char *fmt)
{
const int idx = rb_scan_args_trail_idx(fmt);
return idx+rb_scan_args_isdigit(fmt[idx]);
}
RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_hash(const char *fmt)
{
return (fmt[rb_scan_args_hash_idx(fmt)]==':');
}
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_block_idx(const char *fmt)
{
const int idx = rb_scan_args_hash_idx(fmt);
return idx+(fmt[idx]==':');
}
RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_block(const char *fmt)
{
return (fmt[rb_scan_args_block_idx(fmt)]=='&');
}
# if 0
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_end_idx(const char *fmt)
{
const int idx = rb_scan_args_block_idx(fmt);
return idx+(fmt[idx]=='&');
}
# endif
/* NOTE: Use `char *fmt` instead of `const char *fmt` because of clang's bug*/
/* https://bugs.llvm.org/show_bug.cgi?id=38095 */
# define rb_scan_args0(argc, argv, fmt, varc, vars) \
rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, \
rb_scan_args_n_lead(fmt), \
rb_scan_args_n_opt(fmt), \
rb_scan_args_n_trail(fmt), \
rb_scan_args_f_var(fmt), \
rb_scan_args_f_hash(fmt), \
rb_scan_args_f_block(fmt), \
(rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
# define rb_scan_args_kw0(kw_flag, argc, argv, fmt, varc, vars) \
rb_scan_args_set(kw_flag, argc, argv, \
rb_scan_args_n_lead(fmt), \
rb_scan_args_n_opt(fmt), \
rb_scan_args_n_trail(fmt), \
rb_scan_args_f_var(fmt), \
rb_scan_args_f_hash(fmt), \
rb_scan_args_f_block(fmt), \
(rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_set(int kw_flag, int argc, const VALUE *argv,
int n_lead, int n_opt, int n_trail,
bool f_var, bool f_hash, bool f_block,
VALUE *vars[], RB_UNUSED_VAR(const char *fmt), RB_UNUSED_VAR(int varc))
RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) < 0, "bad scan arg format", "error")
RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) != varc, "variable argument length doesn't match", "error")
{
int i, argi = 0, vari = 0;
VALUE *var, hash = Qnil;
#define rb_scan_args_next_param() vars[vari++]
const int n_mand = n_lead + n_trail;
/* capture an option hash - phase 1: pop from the argv */
if (f_hash && argc > 0) {
VALUE last = argv[argc - 1];
if (rb_scan_args_keyword_p(kw_flag, last)) {
hash = rb_hash_dup(last);
argc--;
}
}
if (argc < n_mand) {
goto argc_error;
}
/* capture leading mandatory arguments */
for (i = 0; i < n_lead; i++) {
var = rb_scan_args_next_param();
if (var) *var = argv[argi];
argi++;
}
/* capture optional arguments */
for (i = 0; i < n_opt; i++) {
var = rb_scan_args_next_param();
if (argi < argc - n_trail) {
if (var) *var = argv[argi];
argi++;
}
else {
if (var) *var = Qnil;
}
}
/* capture variable length arguments */
if (f_var) {
int n_var = argc - argi - n_trail;
var = rb_scan_args_next_param();
if (0 < n_var) {
if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
argi += n_var;
}
else {
if (var) *var = rb_ary_new();
}
}
/* capture trailing mandatory arguments */
for (i = 0; i < n_trail; i++) {
var = rb_scan_args_next_param();
if (var) *var = argv[argi];
argi++;
}
/* capture an option hash - phase 2: assignment */
if (f_hash) {
var = rb_scan_args_next_param();
if (var) *var = hash;
}
/* capture iterator block */
if (f_block) {
var = rb_scan_args_next_param();
if (rb_block_given_p()) {
*var = rb_block_proc();
}
else {
*var = Qnil;
}
}
if (argi == argc) {
return argc;
}
argc_error:
rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
UNREACHABLE_RETURN(-1);
#undef rb_scan_args_next_param
}
/** @endcond */
#if defined(__DOXYGEN__)
# /* don't bother */
#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# /* skip */
#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* skip */
#elif ! defined(__OPTIMIZE__)
# /* skip */
#elif defined(HAVE___VA_OPT__)
# define rb_scan_args(argc, argvp, fmt, ...) \
__builtin_choose_expr( \
__builtin_constant_p(fmt), \
rb_scan_args0( \
argc, argvp, fmt, \
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
((VALUE*[]){__VA_ARGS__})), \
(rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
__builtin_choose_expr( \
__builtin_constant_p(fmt), \
rb_scan_args_kw0( \
kw_flag, argc, argvp, fmt, \
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
((VALUE*[]){__VA_ARGS__})), \
(rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
#elif defined(__STRICT_ANSI__)
# /* skip */
#elif defined(__GNUC__)
# define rb_scan_args(argc, argvp, fmt, ...) \
__builtin_choose_expr( \
__builtin_constant_p(fmt), \
rb_scan_args0( \
argc, argvp, fmt, \
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
((VALUE*[]){__VA_ARGS__})), \
(rb_scan_args)(argc, argvp, fmt, __VA_ARGS__))
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
__builtin_choose_expr( \
__builtin_constant_p(fmt), \
rb_scan_args_kw0( \
kw_flag, argc, argvp, fmt, \
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
((VALUE*[]){__VA_ARGS__})), \
(rb_scan_args_kw)(kw_flag, argc, argvp, fmt, __VA_ARGS__ /**/))
#endif
#endif /* RBIMPL_SCAN_ARGS_H */
include/ruby/internal/stdalign.h 0000644 00000011125 15040330605 0012736 0 ustar 00 #ifndef RBIMPL_STDALIGN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STDALIGN_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ALIGNAS / #RBIMPL_ALIGNOF
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
#include "ruby/internal/has/feature.h"
/**
* Wraps (or simulates) `alignas`. This is C++11's `alignas` and is _different_
* from C11 `_Alignas`. For instance,
*
* ```CXX
* typedef struct alignas(128) foo { int foo } foo;
* ```
*
* is a valid C++ while
*
* ```C
* typedef struct _Alignas(128) foo { int foo } foo;
* ```
*
* is an invalid C because:
*
* - You cannot `struct _Alignas`.
* - A `typedef` cannot have alignments.
*/
#if defined(__cplusplus) && RBIMPL_HAS_FEATURE(cxx_alignas)
# define RBIMPL_ALIGNAS alignas
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
# define RBIMPL_ALIGNAS alignas
#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_ALIGNAS alignas
#elif defined(__GXX_EXPERIMENTAL_CXX0X__)
# define RBIMPL_ALIGNAS alignas
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(align)
# define RBIMPL_ALIGNAS(_) __declspec(align(_))
#elif RBIMPL_HAS_ATTRIBUTE(aligned)
# define RBIMPL_ALIGNAS(_) __attribute__((__aligned__(_)))
#else
# define RBIMPL_ALIGNAS(_) /* void */
#endif
/**
* Wraps (or simulates) `alignof`.
*
* We want C11's `_Alignof`. However in spite of its clear language, compilers
* (including GCC and clang) tend to have buggy implementations. We have to
* avoid such things to resort to our own version.
*
* @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023
* @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560
* @see https://bugs.llvm.org/show_bug.cgi?id=26547
*/
#if defined(__DOXYGEN__)
# define RBIMPL_ALIGNOF alignof
#elif defined(__cplusplus)
# /* C++11 `alignof()` can be buggy. */
# /* see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 */
# /* But don't worry, we can use templates. */
# define RBIMPL_ALIGNOF(T) (static_cast<size_t>(ruby::rbimpl_alignof<T>::value))
namespace ruby {
template<typename T>
struct rbimpl_alignof {
typedef struct {
char _;
T t;
} type;
enum {
value = offsetof(type, t)
};
};
}
#elif RBIMPL_COMPILER_IS(MSVC)
# /* Windows have no alignment glitch.*/
# define RBIMPL_ALIGNOF __alignof
#elif defined(HAVE__ALIGNOF)
# /* Autoconf detected availability of a sane `_Alignof()`. */
# define RBIMPL_ALIGNOF(T) RB_GNUC_EXTENSION(_Alignof(T))
#else
# /* :BEWARE: This is the last resort. If your compiler somehow supports
# * querying the alignment of a type, you definitely should use that instead.
# * There are 2 known pitfalls for this fallback implementation:
# *
# * First, it is either an undefined behaviour (C) or an explicit error (C++)
# * to define a struct inside of `offsetof`. C compilers tend to accept such
# * things, but AFAIK C++ has no room to allow.
# *
# * Second, there exist T such that `struct { char _; T t; }` is invalid. A
# * known example is when T is a struct with a flexible array member. Such
# * struct cannot be enclosed into another one.
# */
# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2083.htm */
# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm */
# define RBIMPL_ALIGNOF(T) offsetof(struct { char _; T t; }, t)
#endif
#endif /* RBIMPL_STDALIGN_H */
include/ruby/internal/core.h 0000644 00000003522 15040330605 0012063 0 ustar 00 #ifndef RBIMPL_CORE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CORE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Core data structures, definitions and manipulations.
*/
#include "ruby/internal/core/rarray.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rbignum.h"
#include "ruby/internal/core/rclass.h"
#include "ruby/internal/core/rdata.h"
#include "ruby/internal/core/rfile.h"
#include "ruby/internal/core/rhash.h"
#include "ruby/internal/core/robject.h"
#include "ruby/internal/core/rregexp.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/core/rstruct.h"
#include "ruby/internal/core/rtypeddata.h"
#endif /* RBIMPL_CORE_H */
include/ruby/internal/compiler_since.h 0000644 00000005337 15040330605 0014134 0 ustar 00 #ifndef RBIMPL_COMPILER_SINCE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_SINCE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_COMPILER_SINCE.
*/
#include "ruby/internal/compiler_is.h"
/**
* @brief Checks if the compiler is of given brand and is newer than or equal
* to the passed version.
* @param cc Compiler brand, like `MSVC`.
* @param x Major version.
* @param y Minor version.
* @param z Patchlevel.
* @retval true cc >= x.y.z.
* @retval false otherwise.
*/
#define RBIMPL_COMPILER_SINCE(cc, x, y, z) \
(RBIMPL_COMPILER_IS(cc) && \
((RBIMPL_COMPILER_VERSION_MAJOR > (x)) || \
((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
((RBIMPL_COMPILER_VERSION_MINOR > (y)) || \
((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
(RBIMPL_COMPILER_VERSION_PATCH >= (z)))))))
/**
* @brief Checks if the compiler is of given brand and is older than the
* passed version.
* @param cc Compiler brand, like `MSVC`.
* @param x Major version.
* @param y Minor version.
* @param z Patchlevel.
* @retval true cc < x.y.z.
* @retval false otherwise.
*/
#define RBIMPL_COMPILER_BEFORE(cc, x, y, z) \
(RBIMPL_COMPILER_IS(cc) && \
((RBIMPL_COMPILER_VERSION_MAJOR < (x)) || \
((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
((RBIMPL_COMPILER_VERSION_MINOR < (y)) || \
((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
(RBIMPL_COMPILER_VERSION_PATCH < (z)))))))
#endif /* RBIMPL_COMPILER_SINCE_H */
include/ruby/internal/ctype.h 0000644 00000055071 15040330605 0012265 0 ustar 00 #ifndef RBIMPL_CTYPE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CTYPE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Our own, locale independent, character handling routines.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <ctype.h>
#endif
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
/**
* @name Old character classification macros
*
* What is this #ISPRINT business? Well, according to our VCS and some
* internet surfing, it appears that the initial intent of these macros were to
* mimic codes appear in common in several GNU projects. As far as @shyouhei
* detects they seem to originate GNU regex (that standalone one rather than
* Gnulib or Glibc), and at least date back to 1995.
*
* Let me lawfully quote from a GNU coreutils commit
* https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=49803907f5dbd7646184a8912c9db9b09dcd0f22
*
* > Jim Meyering writes:
* >
* > "... Some ctype macros are valid only for character codes that
* > isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
* > using /bin/cc or gcc but without giving an ansi option). So, all
* > ctype uses should be through macros like ISPRINT... If
* > STDC_HEADERS is defined, then autoconf has verified that the ctype
* > macros don't need to be guarded with references to isascii. ...
* > Defining isascii to 1 should let any compiler worth its salt
* > eliminate the && through constant folding."
* >
* > Bruno Haible adds:
* >
* > "... Furthermore, isupper(c) etc. have an undefined result if c is
* > outside the range -1 <= c <= 255. One is tempted to write isupper(c)
* > with c being of type `char', but this is wrong if c is an 8-bit
* > character >= 128 which gets sign-extended to a negative value.
* > The macro ISUPPER protects against this as well."
*
* So the intent was to reroute old problematic systems that no longer exist.
* At the same time the problems described above no longer hurt us, because we
* decided to completely avoid using system-provided isupper etc. to reinvent
* the wheel. These macros are entirely legacy; please ignore them.
*
* But let me also put stress that GNU people are wise; they use those macros
* only inside of their own implementations and never let them be public. On
* the other hand ruby has thoughtlessly publicised them to 3rd party libraries
* since its beginning, which is a very bad idea. These macros are too easy to
* get conflicted with definitions elsewhere.
*
* New programs should stick to the `rb_` prefixed names.
*
* @note It seems we just mimic the API. We do not share their implementation
* with GPL-ed programs.
*
* @{
*/
#ifndef ISPRINT
# define ISASCII rb_isascii /**< @old{rb_isascii}*/
# define ISPRINT rb_isprint /**< @old{rb_isprint}*/
# define ISGRAPH rb_isgraph /**< @old{rb_isgraph}*/
# define ISSPACE rb_isspace /**< @old{rb_isspace}*/
# define ISUPPER rb_isupper /**< @old{rb_isupper}*/
# define ISLOWER rb_islower /**< @old{rb_islower}*/
# define ISALNUM rb_isalnum /**< @old{rb_isalnum}*/
# define ISALPHA rb_isalpha /**< @old{rb_isalpha}*/
# define ISDIGIT rb_isdigit /**< @old{rb_isdigit}*/
# define ISXDIGIT rb_isxdigit /**< @old{rb_isxdigit}*/
# define ISBLANK rb_isblank /**< @old{rb_isblank}*/
# define ISCNTRL rb_iscntrl /**< @old{rb_iscntrl}*/
# define ISPUNCT rb_ispunct /**< @old{rb_ispunct}*/
#endif
#define TOUPPER rb_toupper /**< @old{rb_toupper}*/
#define TOLOWER rb_tolower /**< @old{rb_tolower}*/
#define STRCASECMP st_locale_insensitive_strcasecmp /**< @old{st_locale_insensitive_strcasecmp}*/
#define STRNCASECMP st_locale_insensitive_strncasecmp /**< @old{st_locale_insensitive_strncasecmp}*/
#define STRTOUL ruby_strtoul /**< @old{ruby_strtoul}*/
/** @} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/** @name locale insensitive functions
* @{
*/
/* In descriptions below, `the POSIX Locale` and `the "C" locale` are tactfully
* used as to whether the described function mimics POSIX or C99. */
RBIMPL_ATTR_NONNULL(())
/**
* Our own locale-insensitive version of `strcasecmp(3)`. The "case" here
* always means that of the POSIX Locale. It doesn't depend on runtime locale
* settings.
*
* @param[in] s1 Comparison LHS.
* @param[in] s2 Comparison RHS.
* @retval -1 `s1` is "less" than `s2`.
* @retval 0 Both strings converted into lowercase would be identical.
* @retval 1 `s1` is "greater" than `s2`.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
*/
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
RBIMPL_ATTR_NONNULL(())
/**
* Our own locale-insensitive version of `strcnasecmp(3)`. The "case" here
* always means that of the POSIX Locale. It doesn't depend on runtime locale
* settings.
*
* @param[in] s1 Comparison LHS.
* @param[in] s2 Comparison RHS.
* @param[in] n Comparison shall stop after first `n` bytes are scanned.
* @retval -1 `s1` is "less" than `s2`.
* @retval 0 Both strings converted into lowercase would be identical.
* @retval 1 `s1` is "greater" than `s2`.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning This function is _not_ timing safe.
*/
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
RBIMPL_ATTR_NONNULL((1))
/**
* Our own locale-insensitive version of `strtoul(3)`. The conversion is done
* as if the current locale is set to the "C" locale, no matter actual runtime
* locale settings.
*
* @note This is needed because `strtoul("i", 0, 36)` would return zero
* if it is locale sensitive and the current locale is `tr_TR`.
* @param[in] str String of digits, optionally preceded with whitespaces
* (ignored) and optionally `+` or `-` sign.
* @param[out] endptr NULL, or an arbitrary pointer (overwritten on return).
* @param[in] base `2` to `36` inclusive for each base, or special case
* `0` to detect the base from the contents of the string.
* @return Converted integer, casted to unsigned long.
* @post If `endptr` is not NULL, it is updated to point the first such
* byte where conversion failed.
* @note This function sets `errno` on failure.
* - `EINVAL`: Passed `base` is out of range.
* - `ERANGE`: Converted integer is out of range of `long`.
* @warning As far as @shyouhei reads ISO/IEC 9899:2018 section 7.22.1.4, a
* conforming `strtoul` implementation shall render `ERANGE`
* whenever it finds the input string represents a negative
* integer. Such thing can never be representable using `unsigned
* long`. However this implementation does not honour that
* language. It just casts such negative value to the return
* type, resulting a very big return value. This behaviour is at
* least questionable. But we can no longer change that at this
* point.
* @note Not only does this function works under the "C" locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
*/
unsigned long ruby_strtoul(const char *str, char **endptr, int base);
RBIMPL_SYMBOL_EXPORT_END()
/*
* We are making the functions below to return `int` instead of `bool`. They
* have been as such since their birth at 5f237d79033b2109afb768bc889611fa9630.
*/
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isascii(3)`.
*
* @param[in] c Byte in question to query.
* @retval false `c` is out of range of ASCII character set.
* @retval true Yes it is.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isascii(int c)
{
return '\0' <= c && c <= '\x7f';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isupper(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "upper".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isupper(int c)
{
return 'A' <= c && c <= 'Z';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `islower(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "lower".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_islower(int c)
{
return 'a' <= c && c <= 'z';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isalpha(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in either IEEE 1003.1 section 7.3.1.1
* "upper" or "lower".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isalpha(int c)
{
return rb_isupper(c) || rb_islower(c);
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isdigit(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "digit".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isdigit(int c)
{
return '0' <= c && c <= '9';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isalnum(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in either IEEE 1003.1 section 7.3.1.1
* "upper", "lower", or "digit".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isalnum(int c)
{
return rb_isalpha(c) || rb_isdigit(c);
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isxdigit(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "xdigit".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isxdigit(int c)
{
return rb_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isblank(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "blank".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isblank(int c)
{
return c == ' ' || c == '\t';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isspace(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "space".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isspace(int c)
{
return c == ' ' || ('\t' <= c && c <= '\r');
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `iscntrl(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "cntrl".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_iscntrl(int c)
{
return ('\0' <= c && c < ' ') || c == '\x7f';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to rb_isgraph(), except it also returns true for `' '`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in either IEEE 1003.1 section 7.3.1.1
* "upper", "lower", "digit", "punct", or a `' '`.
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isprint(int c)
{
return ' ' <= c && c <= '\x7e';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `ispunct(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in IEEE 1003.1 section 7.3.1.1 "punct".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_ispunct(int c)
{
return !rb_isalnum(c);
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `isgraph(3)`.
*
* @param[in] c Byte in question to query.
* @retval true `c` is listed in either IEEE 1003.1 section 7.3.1.1
* "upper", "lower", "digit", or "punct".
* @retval false Anything else.
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_isgraph(int c)
{
return '!' <= c && c <= '\x7e';
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `tolower(3)`.
*
* @param[in] c Byte in question to convert.
* @retval c The byte is not listed in in IEEE 1003.1 section
* 7.3.1.1 "upper".
* @retval otherwise Byte converted using the map defined in IEEE 1003.1
* section 7.3.1 "tolower".
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_tolower(int c)
{
return rb_isupper(c) ? (c|0x20) : c;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Our own locale-insensitive version of `toupper(3)`.
*
* @param[in] c Byte in question to convert.
* @retval c The byte is not listed in in IEEE 1003.1 section
* 7.3.1.1 "lower".
* @retval otherwise Byte converted using the map defined in IEEE 1003.1
* section 7.3.1 "toupper".
* @note Not only does this function works under the POSIX Locale, but
* also assumes its execution character set be what ruby calls an
* ASCII-compatible character set; which does not include for
* instance EBCDIC or UTF-16LE.
* @warning `c` is an int. This means that when you pass a `char` value
* here, it experiences "integer promotion" as defined in ISO/IEC
* 9899:2018 section 6.3.1.1 paragraph 1.
*/
static inline int
rb_toupper(int c)
{
return rb_islower(c) ? (c&0x5f) : c;
}
/** @} */
#endif /* RBIMPL_CTYPE_H */
include/ruby/internal/eval.h 0000644 00000044315 15040330605 0012067 0 ustar 00 #ifndef RBIMPL_EVAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_EVAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Declares ::rb_eval_string().
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
* Evaluates the given string.
*
* In case it is called from within a C-backended method, the evaluation is
* done under the current binding. However there can be no method. On such
* situation this function evaluates in an isolated binding, like `require`
* runs in a separate one.
*
* `__FILE__` will be `"(eval)"`, and `__LINE__` starts from 1 in the
* evaluation.
*
* @param[in] str Ruby code to evaluate.
* @exception rb_eException Raises an exception on error.
* @return The evaluated result.
*
* @internal
*
* @shyouhei's old tale about the birth and growth of this function:
*
* At the beginning, there was no rb_eval_string(). @shyouhei heard that
* @shugo, author of Apache httpd's mod_ruby module, requested @matz for this
* API. He wanted a way so that mod_ruby can evaluate ruby scripts one by one,
* separately, in each different contexts. So this function was made. It was
* designed to be a global interpreter entry point like ruby_run_node().
*
* The way it is implemented however allows extension libraries (not just
* programs like Apache httpd) to call this function. Because its name says
* nothing about the initial design, people started to think of it as an
* orthodox way to call ruby level `eval` method from their extension
* libraries. Even our `extension.rdoc` has had a description of this function
* basically according to this understanding.
*
* The old (mod_ruby like) usage still works. But over time, usages of this
* function from extension libraries got popular, while mod_ruby faded out; is
* no longer maintained now. Devs decided to actively support both. This
* function now auto-detects how it is called, and switches how it works
* depending on it.
*
* @see https://bugs.ruby-lang.org/issues/18780
*/
VALUE rb_eval_string(const char *str);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_eval_string(), except it avoids potential global escapes.
* Such global escapes include exceptions, `throw`, `break`, for example.
*
* It first evaluates the given string as rb_eval_string() does. If no global
* escape occurred during the evaluation, it returns the result and `*state` is
* zero. Otherwise, it returns some undefined value and sets `*state` to
* nonzero. If state is `NULL`, it is not set in both cases.
*
* @param[in] str Ruby code to evaluate.
* @param[out] state State of execution.
* @return The evaluated result if succeeded, an undefined value if
* otherwise.
* @post `*state` is set to zero if succeeded. Nonzero otherwise.
* @warning You have to clear the error info with `rb_set_errinfo(Qnil)` if
* you decide to ignore the caught exception.
* @see rb_eval_string
* @see rb_protect
*
* @internal
*
* The "undefined value" described above is in fact ::RUBY_Qnil for now. But
* @shyouhei doesn't think that we would never change that.
*
* Though not a part of our public API, `state` is in fact an
* enum ruby_tag_type. You can see the potential "nonzero" values by looking
* at vm_core.h.
*/
VALUE rb_eval_string_protect(const char *str, int *state);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_eval_string_protect(), except it evaluates the given string
* under a module binding in an isolated binding. This is the same as a
* binding for loaded libraries on `rb_load(something, true)`.
*
* @param[in] str Ruby code to evaluate.
* @param[out] state State of execution.
* @return The evaluated result if succeeded, an undefined value if
* otherwise.
* @post `*state` is set to zero if succeeded. Nonzero otherwise.
* @warning You have to clear the error info with `rb_set_errinfo(Qnil)` if
* you decide to ignore the caught exception.
* @see rb_eval_string
*/
VALUE rb_eval_string_wrap(const char *str, int *state);
/**
* Calls a method. Can call both public and private methods.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] n Number of arguments that follow.
* @param[in] ... Arbitrary number of method arguments.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcall(VALUE recv, ID mid, int n, ...);
/**
* Identical to rb_funcall(), except it takes the method arguments as a C
* array.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv);
/**
* Identical to rb_funcallv(), except you can specify how to handle the last
* element of the given array.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
/**
* Identical to rb_funcallv(), except it only takes public methods into
* account. This is roughly Ruby's `Object#public_send`.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv);
/**
* Identical to rb_funcallv_public(), except you can specify how to handle the
* last element of the given array. It can also be seen as a routine identical
* to rb_funcallv_kw(), except it only takes public methods into account.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
/**
* @deprecated This is an old name of rb_funcallv(). Provided here for
* backwards compatibility to 2.x programs (introduced in 2.1).
* It is not a good name. Please don't use it any longer.
*/
#define rb_funcall2 rb_funcallv
/**
* @deprecated This is an old name of rb_funcallv_public(). Provided here
* for backwards compatibility to 2.x programs (introduced in
* 2.1). It is not a good name. Please don't use it any longer.
*/
#define rb_funcall3 rb_funcallv_public
/**
* Identical to rb_funcallv_public(), except you can pass the passed block.
*
* Sometimes you want to "pass" a block parameter form one method to another.
* Suppose you have this Ruby method `foo`:
*
* ```ruby
* def foo(x, y, &z)
* x.open(y, &z)
* end
* ```
*
* And suppose you want to translate this into C. Then
* rb_funcall_passing_block() function is usable in this situation.
*
* ```CXX
* VALUE
* foo_translated_into_C(VALUE self, VALUE x, VALUE y)
* {
* const auto open = rb_intern("open");
*
* return rb_funcall_passing_block(x, open, 1, &y);
* }
* ```
*
* @see rb_yield_block
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv);
/**
* Identical to rb_funcallv_passing_block(), except you can specify how to
* handle the last element of the given array. It can also be seen as a
* routine identical to rb_funcallv_public_kw(), except you can pass the passed
* block.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
/**
* Identical to rb_funcallv_public(), except you can pass a block. A block
* here basically is an instance of ::rb_cProc. If you want to exercise
* `to_proc` conversion, do so before passing it here. However nil and symbols
* are special-case allowed.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] procval An instance of Proc, Symbol, or NilClass.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*
* @internal
*
* Implementation-wise, `procval` is in fact a "block handler" object. You
* could also pass an IFUNC (block_handler_ifunc) here to say precise. --- But
* AFAIK there is no 3rd party way to even know that there are objects called
* IFUNC behind-the-scene.
*/
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval);
/**
* Identical to rb_funcallv_with_block(), except you can specify how to handle
* the last element of the given array. It can also be seen as a routine
* identical to rb_funcallv_public_kw(), except you can pass a block.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] procval An instance of Proc, Symbol, or NilClass.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No such method.
* @exception rb_eNoMethodError The method is private or protected.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
*/
VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval, int kw_splat);
/**
* This resembles ruby's `super`.
*
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @exception rb_eNoMethodError No super method are there.
* @exception rb_eException Any exceptions happen inside.
* @return What the super method evaluates to.
*/
VALUE rb_call_super(int argc, const VALUE *argv);
/**
* Identical to rb_call_super(), except you can specify how to handle the last
* element of the given array.
*
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @exception rb_eNoMethodError No super method are there.
* @exception rb_eException Any exceptions happen inside.
* @return What the super method evaluates to.
*/
VALUE rb_call_super_kw(int argc, const VALUE *argv, int kw_splat);
/**
* This resembles ruby's `self`.
*
* @exception rb_eRuntimeError Called from outside of method context.
* @return Current receiver.
*/
VALUE rb_current_receiver(void);
RBIMPL_ATTR_NONNULL((2))
/**
* Keyword argument deconstructor.
*
* Retrieves argument values bound to keywords, which directed by `table` into
* `values`, deleting retrieved entries from `keyword_hash` along the way.
* First `required` number of IDs referred by `table` are mandatory, and
* succeeding `optional` (`-optional-1` if `optional` is negative) number of
* IDs are optional. If a mandatory key is not contained in `keyword_hash`,
* raises ::rb_eArgError. If an optional key is not present in `keyword_hash`,
* the corresponding element in `values` is set to ::RUBY_Qundef. If
* `optional` is negative, rest of `keyword_hash` are ignored, otherwise raises
* ::rb_eArgError.
*
* @warning Handling keyword arguments in the C API is less efficient than
* handling them in Ruby. Consider using a Ruby wrapper method
* around a non-keyword C function.
* @see https://bugs.ruby-lang.org/issues/11339
* @param[out] keyword_hash Target hash to deconstruct.
* @param[in] table List of keywords that you are interested in.
* @param[in] required Number of mandatory keywords.
* @param[in] optional Number of optional keywords (can be negative).
* @param[out] values Buffer to be filled.
* @exception rb_eArgError Absence of a mandatory keyword.
* @exception rb_eArgError Found an unknown keyword.
* @return Number of found values that are stored into `values`.
*/
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values);
RBIMPL_ATTR_NONNULL(())
/**
* Splits a hash into two.
*
* Takes a hash of various keys, and split it into symbol-keyed parts and
* others. Symbol-keyed part becomes the return value. What remains are
* returned as a new hash object stored at the argument pointer.
*
* @param[in,out] orighash Pointer to a target hash to split.
* @return An extracted keyword hash.
* @post Upon successful return `orighash` points to another hash
* object, whose contents are the remainder of the operation.
* @note The argument hash object is not modified.
*/
VALUE rb_extract_keywords(VALUE *orighash);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_EVAL_H */
include/ruby/internal/special_consts.h 0000644 00000027627 15040330605 0014160 0 ustar 00 #ifndef RBIMPL_SPECIAL_CONSTS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SPECIAL_CONSTS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines enum ::ruby_special_consts.
* @see Sasada, K., "A Lightweight Representation of Floating-Point
* Numbers on Ruby Interpreter", in proceedings of 10th JSSST
* SIGPPL Workshop on Programming and Programming Languages
* (PPL2008), pp. 9-16, 2008.
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/enum_extensibility.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
/**
* @private
* @warning Do not touch this macro.
* @warning It is an implementation detail.
* @warning The value of this macro must match for ruby itself and all
* extension libraries, otherwise serious memory corruption shall
* occur.
*/
#if defined(USE_FLONUM)
# /* Take that. */
#elif SIZEOF_VALUE >= SIZEOF_DOUBLE
# define USE_FLONUM 1
#else
# define USE_FLONUM 0
#endif
/** This is an old name of #RB_TEST. Not sure which name is preferred. */
#define RTEST RB_TEST
#define FIXNUM_P RB_FIXNUM_P /**< @old{RB_FIXNUM_P} */
#define IMMEDIATE_P RB_IMMEDIATE_P /**< @old{RB_IMMEDIATE_P} */
#define NIL_P RB_NIL_P /**< @old{RB_NIL_P} */
#define SPECIAL_CONST_P RB_SPECIAL_CONST_P /**< @old{RB_SPECIAL_CONST_P} */
#define STATIC_SYM_P RB_STATIC_SYM_P /**< @old{RB_STATIC_SYM_P} */
#define Qfalse RUBY_Qfalse /**< @old{RUBY_Qfalse} */
#define Qnil RUBY_Qnil /**< @old{RUBY_Qnil} */
#define Qtrue RUBY_Qtrue /**< @old{RUBY_Qtrue} */
#define Qundef RUBY_Qundef /**< @old{RUBY_Qundef} */
#define FIXNUM_FLAG RUBY_FIXNUM_FLAG /**< @old{RUBY_FIXNUM_FLAG} */
#define FLONUM_FLAG RUBY_FLONUM_FLAG /**< @old{RUBY_FLONUM_FLAG} */
#define FLONUM_MASK RUBY_FLONUM_MASK /**< @old{RUBY_FLONUM_MASK} */
#define FLONUM_P RB_FLONUM_P /**< @old{RB_FLONUM_P} */
#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK /**< @old{RUBY_IMMEDIATE_MASK} */
#define SYMBOL_FLAG RUBY_SYMBOL_FLAG /**< @old{RUBY_SYMBOL_FLAG} */
/** @cond INTERNAL_MACRO */
#define RB_FIXNUM_P RB_FIXNUM_P
#define RB_FLONUM_P RB_FLONUM_P
#define RB_IMMEDIATE_P RB_IMMEDIATE_P
#define RB_NIL_P RB_NIL_P
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define RB_STATIC_SYM_P RB_STATIC_SYM_P
#define RB_TEST RB_TEST
#define RB_UNDEF_P RB_UNDEF_P
#define RB_NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
/** @endcond */
/** special constants - i.e. non-zero and non-fixnum constants */
enum
RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
ruby_special_consts {
#if defined(__DOXYGEN__)
RUBY_Qfalse, /**< @see ::rb_cFalseClass */
RUBY_Qtrue, /**< @see ::rb_cTrueClass */
RUBY_Qnil, /**< @see ::rb_cNilClass */
RUBY_Qundef, /**< Represents so-called undef. */
RUBY_IMMEDIATE_MASK, /**< Bit mask detecting special consts. */
RUBY_FIXNUM_FLAG, /**< Flag to denote a fixnum. */
RUBY_FLONUM_MASK, /**< Bit mask detecting a flonum. */
RUBY_FLONUM_FLAG, /**< Flag to denote a flonum. */
RUBY_SYMBOL_FLAG, /**< Flag to denote a static symbol. */
#elif USE_FLONUM
RUBY_Qfalse = 0x00, /* ...0000 0000 */
RUBY_Qnil = 0x04, /* ...0000 0100 */
RUBY_Qtrue = 0x14, /* ...0001 0100 */
RUBY_Qundef = 0x24, /* ...0010 0100 */
RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
RUBY_FLONUM_MASK = 0x03, /* ...0000 0011 */
RUBY_FLONUM_FLAG = 0x02, /* ...xxxx xx10 */
RUBY_SYMBOL_FLAG = 0x0c, /* ...xxxx 1100 */
#else
RUBY_Qfalse = 0x00, /* ...0000 0000 */
RUBY_Qnil = 0x02, /* ...0000 0010 */
RUBY_Qtrue = 0x06, /* ...0000 0110 */
RUBY_Qundef = 0x0a, /* ...0000 1010 */
RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
RUBY_FLONUM_FLAG = 0x02, /* ...0000 0010 */
RUBY_SYMBOL_FLAG = 0x0e, /* ...xxxx 1110 */
#endif
RUBY_SPECIAL_SHIFT = 8 /**< Least significant 8 bits are reserved. */
};
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Emulates Ruby's "if" statement.
*
* @param[in] obj An arbitrary ruby object.
* @retval false `obj` is either ::RUBY_Qfalse or ::RUBY_Qnil.
* @retval true Anything else.
*
* @internal
*
* It HAS to be `__attribute__((const))` in order for clang to properly deduce
* `__builtin_assume()`.
*/
static inline bool
RB_TEST(VALUE obj)
{
/*
* if USE_FLONUM
* Qfalse: ....0000 0000
* Qnil: ....0000 0100
* ~Qnil: ....1111 1011
* v ....xxxx xxxx
* ----------------------------
* RTEST(v) ....xxxx x0xx
*
* if ! USE_FLONUM
* Qfalse: ....0000 0000
* Qnil: ....0000 0010
* ~Qnil: ....1111 1101
* v ....xxxx xxxx
* ----------------------------
* RTEST(v) ....xxxx xx0x
*
* RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
*/
return obj & ~RUBY_Qnil;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is nil.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is ::RUBY_Qnil.
* @retval false Anything else.
*/
static inline bool
RB_NIL_P(VALUE obj)
{
return obj == RUBY_Qnil;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is undef.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is ::RUBY_Qundef.
* @retval false Anything else.
*/
static inline bool
RB_UNDEF_P(VALUE obj)
{
return obj == RUBY_Qundef;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is nil or undef. Can be used to see if
* a keyword argument is not given or given `nil`.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is ::RUBY_Qnil or ::RUBY_Qundef.
* @retval false Anything else.
*/
static inline bool
RB_NIL_OR_UNDEF_P(VALUE obj)
{
/*
* if USE_FLONUM
* Qundef: ....0010 0100
* Qnil: ....0000 0100
* mask: ....1101 1111
* common_bits: ....0000 0100
* ---------------------------------
* Qnil & mask ....0000 0100
* Qundef & mask ....0000 0100
*
* if ! USE_FLONUM
* Qundef: ....0000 1010
* Qnil: ....0000 0010
* mask: ....1111 0111
* common_bits: ....0000 0010
* ----------------------------
* Qnil & mask ....0000 0010
* Qundef & mask ....0000 0010
*
* NIL_OR_UNDEF_P(v) can be true only when v is Qundef or Qnil.
*/
const VALUE mask = ~(RUBY_Qundef ^ RUBY_Qnil);
const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
return (obj & mask) == common_bits;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is a so-called Fixnum.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is a Fixnum.
* @retval false Anything else.
* @note Fixnum was a thing in the 20th century, but it is rather an
* implementation detail today.
*/
static inline bool
RB_FIXNUM_P(VALUE obj)
{
return obj & RUBY_FIXNUM_FLAG;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is a static symbol.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is a static symbol
* @retval false Anything else.
* @see RB_DYNAMIC_SYM_P()
* @see RB_SYMBOL_P()
* @note These days there are static and dynamic symbols, just like we
* once had Fixnum/Bignum back in the old days.
*/
static inline bool
RB_STATIC_SYM_P(VALUE obj)
{
RBIMPL_ATTR_CONSTEXPR(CXX14)
const VALUE mask = ~(RBIMPL_VALUE_FULL << RUBY_SPECIAL_SHIFT);
return (obj & mask) == RUBY_SYMBOL_FLAG;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is a so-called Flonum.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is a Flonum.
* @retval false Anything else.
* @see RB_FLOAT_TYPE_P()
* @note These days there are Flonums and non-Flonum floats, just like we
* once had Fixnum/Bignum back in the old days.
*/
static inline bool
RB_FLONUM_P(VALUE obj)
{
#if USE_FLONUM
return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
#else
return false;
#endif
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is an immediate i.e. an object which has no
* corresponding storage inside of the object space.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is a Flonum.
* @retval false Anything else.
* @see RB_FLOAT_TYPE_P()
* @note The concept of "immediate" is purely C specific.
*/
static inline bool
RB_IMMEDIATE_P(VALUE obj)
{
return obj & RUBY_IMMEDIATE_MASK;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if the given object is of enum ::ruby_special_consts.
*
* @param[in] obj An arbitrary ruby object.
* @retval true `obj` is a special constant.
* @retval false Anything else.
*/
static inline bool
RB_SPECIAL_CONST_P(VALUE obj)
{
return RB_IMMEDIATE_P(obj) || obj == RUBY_Qfalse;
}
RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
/**
* Identical to RB_SPECIAL_CONST_P, except it returns a ::VALUE.
*
* @param[in] obj An arbitrary ruby object.
* @retval RUBY_Qtrue `obj` is a special constant.
* @retval RUBY_Qfalse Anything else.
*
* @internal
*
* This function is to mimic old rb_special_const_p macro but have anyone
* actually used its return value? Wasn't it just something no one needed?
*/
static inline VALUE
rb_special_const_p(VALUE obj)
{
return RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
}
/**
* @cond INTERNAL_MACRO
* See [ruby-dev:27513] for the following macros.
*/
#define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
#define RUBY_Qtrue RBIMPL_CAST((VALUE)RUBY_Qtrue)
#define RUBY_Qnil RBIMPL_CAST((VALUE)RUBY_Qnil)
#define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
/** @endcond */
#endif /* RBIMPL_SPECIAL_CONSTS_H */
include/ruby/internal/event.h 0000644 00000014117 15040330605 0012256 0 ustar 00 #ifndef RBIMPL_EVENT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_EVENT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Debugging and tracing APIs.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
/* These macros are not enums because they are wider than int.*/
/**
* @name Traditional set_trace_func events
*
* @{
*/
#define RUBY_EVENT_NONE 0x0000 /**< No events. */
#define RUBY_EVENT_LINE 0x0001 /**< Encountered a new line. */
#define RUBY_EVENT_CLASS 0x0002 /**< Encountered a new class. */
#define RUBY_EVENT_END 0x0004 /**< Encountered an end of a class clause. */
#define RUBY_EVENT_CALL 0x0008 /**< A method, written in Ruby, is called. */
#define RUBY_EVENT_RETURN 0x0010 /**< Encountered a `return` statement. */
#define RUBY_EVENT_C_CALL 0x0020 /**< A method, written in C, is called. */
#define RUBY_EVENT_C_RETURN 0x0040 /**< Return from a method, written in C. */
#define RUBY_EVENT_RAISE 0x0080 /**< Encountered a `raise` statement. */
#define RUBY_EVENT_ALL 0x00ff /**< Bitmask of traditional events. */
/** @} */
/**
* @name TracePoint extended events
*
* @{
*/
#define RUBY_EVENT_B_CALL 0x0100 /**< Encountered an `yield` statement. */
#define RUBY_EVENT_B_RETURN 0x0200 /**< Encountered a `next` statement. */
#define RUBY_EVENT_THREAD_BEGIN 0x0400 /**< Encountered a new thread. */
#define RUBY_EVENT_THREAD_END 0x0800 /**< Encountered an end of a thread. */
#define RUBY_EVENT_FIBER_SWITCH 0x1000 /**< Encountered a `Fiber#yield`. */
#define RUBY_EVENT_SCRIPT_COMPILED 0x2000 /**< Encountered an `eval`. */
#define RUBY_EVENT_TRACEPOINT_ALL 0xffff /**< Bitmask of extended events. */
/** @} */
/**
* @name Special events
*
* @internal
*
* These bits are actually used internally. See vm_core.h if you are curious.
*
* @endinternal
*
* @{
*/
#define RUBY_EVENT_RESERVED_FOR_INTERNAL_USE 0x030000 /**< Opaque bits. */
/** @} */
/**
* @name Internal events
*
* @shyouhei's understanding is that some of them are visible from extension
* libraries because of `ext/objspace`. But it seems that doesn't describe
* everything? The ultimate reason why they are here remains unclear.
*
* @{
*/
#define RUBY_INTERNAL_EVENT_SWITCH 0x040000 /**< Thread switched. */
#define RUBY_EVENT_SWITCH 0x040000 /**< @old{RUBY_INTERNAL_EVENT_SWITCH} */
/* 0x080000 */
#define RUBY_INTERNAL_EVENT_NEWOBJ 0x100000 /**< Object allocated. */
#define RUBY_INTERNAL_EVENT_FREEOBJ 0x200000 /**< Object swept. */
#define RUBY_INTERNAL_EVENT_GC_START 0x400000 /**< GC started. */
#define RUBY_INTERNAL_EVENT_GC_END_MARK 0x800000 /**< GC ended mark phase. */
#define RUBY_INTERNAL_EVENT_GC_END_SWEEP 0x1000000 /**< GC ended sweep phase. */
#define RUBY_INTERNAL_EVENT_GC_ENTER 0x2000000 /**< `gc_enter()` is called. */
#define RUBY_INTERNAL_EVENT_GC_EXIT 0x4000000 /**< `gc_exit()` is called. */
#define RUBY_INTERNAL_EVENT_OBJSPACE_MASK 0x7f00000 /**< Bitmask of GC events. */
#define RUBY_INTERNAL_EVENT_MASK 0xffff0000 /**< Bitmask of internal events. */
/** @} */
/**
* Represents event(s). As the name implies events are bit flags.
*/
typedef uint32_t rb_event_flag_t;
/**
* Type of event hooks. When an event happens registered functions are kicked
* with appropriate parameters.
*
* @param[in] evflag The kind of event that happened.
* @param[in] data The `data` passed to rb_add_event_hook().
* @param[in] self Current receiver.
* @param[in] mid Name of the current method.
* @param[in] klass Current class.
*/
typedef void (*rb_event_hook_func_t)(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass);
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Registers an event hook function.
*
* @param[in] func A callback.
* @param[in] events A set of events that `func` should run.
* @param[in] data Passed as-is to `func`.
*/
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);
/**
* Removes the passed function from the list of event hooks.
*
* @param[in] func A callback.
* @return Number of deleted event hooks.
* @note As multiple events can share the same `func` it is quite
* possible for the return value to become more than one.
*
* @internal
*
* @shyouhei doesn't know if this is an Easter egg or an official feature, but
* you can pass 0 to the argument. That effectively swipes everything out from
* the hook list.
*/
int rb_remove_event_hook(rb_event_hook_func_t func);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_EVENT_H */
include/ruby/internal/static_assert.h 0000644 00000006217 15040330605 0014007 0 ustar 00 #ifndef RBIMPL_STATIC_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STATIC_ASSERT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_STATIC_ASSERT.
*/
#include <assert.h>
#include "ruby/internal/has/extension.h"
#include "ruby/internal/compiler_since.h"
/** @cond INTERNAL_MACRO */
#if defined(__cplusplus) && defined(__cpp_static_assert)
# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
# define RBIMPL_STATIC_ASSERT0 static_assert
#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
# define RBIMPL_STATIC_ASSERT0 static_assert
#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_STATIC_ASSERT0 static_assert
#elif defined(__cplusplus) && __cplusplus >= 201103L
# define RBIMPL_STATIC_ASSERT0 static_assert
#elif defined(__cplusplus) && RBIMPL_HAS_EXTENSION(cxx_static_assert)
# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert
#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert
#elif defined(__STDC_VERSION__) && RBIMPL_HAS_EXTENSION(c_static_assert)
# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
#elif defined(__STDC_VERSION__) && RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
#elif defined(static_assert)
# /* Take <assert.h> definition */
# define RBIMPL_STATIC_ASSERT0 static_assert
#endif
/** @endcond */
/**
* @brief Wraps (or simulates) `static_assert`
* @param name Valid C/C++ identifier, describing the assertion.
* @param expr Expression to assert.
* @note `name` shall not be a string literal.
*/
#if defined(__DOXYGEN__)
# define RBIMPL_STATIC_ASSERT static_assert
#elif defined(RBIMPL_STATIC_ASSERT0)
# define RBIMPL_STATIC_ASSERT(name, expr) \
RBIMPL_STATIC_ASSERT0(expr, # name ": " # expr)
#else
# define RBIMPL_STATIC_ASSERT(name, expr) \
typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)]
#endif
#endif /* RBIMPL_STATIC_ASSERT_H */
include/ruby/internal/stdbool.h 0000644 00000004007 15040330605 0012600 0 ustar 00 #ifndef RBIMPL_STDBOOL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STDBOOL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief C99 shim for <stdbool.h>
*/
#include "ruby/internal/config.h"
#if defined(__bool_true_false_are_defined)
# /* Take that. */
#elif defined(__cplusplus)
# /* bool is a keyword in C++. */
# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
# include <cstdbool>
# endif
#
# ifndef __bool_true_false_are_defined
# define __bool_true_false_are_defined
# endif
#elif defined(HAVE_STDBOOL_H)
# /* Take stdbool.h definition. */
# include <stdbool.h>
#elif !defined(HAVE__BOOL)
typedef unsigned char _Bool;
# /* See also http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2229.htm */
# define bool _Bool
# define true ((_Bool)+1)
# define false ((_Bool)+0)
# define __bool_true_false_are_defined
#endif
#endif /* RBIMPL_STDBOOL_H */
include/ruby/internal/compiler_is/intel.h 0000644 00000004011 15040330605 0014545 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_INTEL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_INTEL_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_Intel.
*/
#if ! defined(__INTEL_COMPILER)
# define RBIMPL_COMPILER_IS_Intel 0
#elif ! defined(__INTEL_COMPILER_UPDATE)
# define RBIMPL_COMPILER_IS_Intel 1
# /* __INTEL_COMPILER = XXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
# define RBIMPL_COMPILER_VERSION_PATCH (__INTEL_COMPILER % 10)
#else
# define RBIMPL_COMPILER_IS_Intel 1
# /* __INTEL_COMPILER = XXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
# define RBIMPL_COMPILER_VERSION_PATCH __INTEL_COMPILER_UPDATE
#endif
#endif /* RBIMPL_COMPILER_IS_INTEL_H */
include/ruby/internal/compiler_is/apple.h 0000644 00000003732 15040330605 0014544 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_APPLE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_APPLE_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_Apple.
*
* Apple ships clang. Problem is, its `__clang_major__` etc. are not the
* upstream LLVM version, but XCode's. We have to think Apple's is distinct
* from LLVM's, when it comes to compiler detection business in this header
* file.
*/
#if ! defined(__clang__)
# define RBIMPL_COMPILER_IS_Apple 0
#elif ! defined(__apple_build_version__)
# define RBIMPL_COMPILER_IS_Apple 0
#else
# define RBIMPL_COMPILER_IS_Apple 1
# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
#endif
#endif /* RBIMPL_COMPILER_IS_APPLE_H */
include/ruby/internal/compiler_is/msvc.h 0000644 00000004736 15040330605 0014420 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_MSVC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_MSVC_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_MSVC.
*/
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/intel.h"
#if ! defined(_MSC_VER)
# define RBIMPL_COMPILER_IS_MSVC 0
#elif RBIMPL_COMPILER_IS(Clang)
# define RBIMPL_COMPILER_IS_MSVC 0
#elif RBIMPL_COMPILER_IS(Intel)
# define RBIMPL_COMPILER_IS_MSVC 0
#elif _MSC_VER >= 1400
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_FULL_VER = XXYYZZZZZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 10000000)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 10000000 / 100000)
# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER % 100000)
#elif defined(_MSC_FULL_VER)
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_FULL_VER = XXYYZZZZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 1000000)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 1000000 / 10000)
# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER % 10000)
#else
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_VER = XXYY */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_VER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_VER % 100)
# define RBIMPL_COMPILER_VERSION_PATCH 0
#endif
#endif /* RBIMPL_COMPILER_IS_MSVC_H */
include/ruby/internal/compiler_is/clang.h 0000644 00000003403 15040330605 0014522 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_CLANG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_CLANG_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_Clang.
*/
#include "ruby/internal/compiler_is/apple.h"
#if ! defined(__clang__)
# define RBIMPL_COMPILER_IS_Clang 0
#elif RBIMPL_COMPILER_IS(Apple)
# define RBIMPL_COMPILER_IS_Clang 0
#else
# define RBIMPL_COMPILER_IS_Clang 1
# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
#endif
#endif /* RBIMPL_COMPILER_IS_CLANG_H */
include/ruby/internal/compiler_is/sunpro.h 0000644 00000005223 15040330605 0014766 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_SUNPRO_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_SUNPRO_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_SunPro.
*/
#if ! (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# define RBIMPL_COMPILER_IS_SunPro 0
#elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x5100
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_C = 0xXYYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_C >> 12)
# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_C >> 8 & 0xF) * 10 + (__SUNPRO_C >> 4 & 0xF))
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_C & 0xF)
#elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5100
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_CC = 0xXYYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_CC >> 12)
# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_CC >> 8 & 0xF) * 10 + (__SUNPRO_CC >> 4 & 0xF))
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_CC & 0xF)
#elif defined(__SUNPRO_C)
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_C = 0xXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_C >> 8)
# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_C >> 4 & 0xF)
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_C & 0xF)
#else
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_CC = 0xXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_CC >> 8)
# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_CC >> 4 & 0xF)
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_CC & 0xF)
#endif
#endif /* RBIMPL_COMPILER_IS_SUNPRO_H */
include/ruby/internal/compiler_is/gcc.h 0000644 00000003715 15040330605 0014200 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_GCC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_GCC_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_COMPILER_IS_GCC.
*/
#include "ruby/internal/compiler_is/apple.h"
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/intel.h"
#if ! defined(__GNUC__)
# define RBIMPL_COMPILER_IS_GCC 0
#elif RBIMPL_COMPILER_IS(Apple)
# define RBIMPL_COMPILER_IS_GCC 0
#elif RBIMPL_COMPILER_IS(Clang)
# define RBIMPL_COMPILER_IS_GCC 0
#elif RBIMPL_COMPILER_IS(Intel)
# define RBIMPL_COMPILER_IS_GCC 0
#else
# define RBIMPL_COMPILER_IS_GCC 1
# define RBIMPL_COMPILER_VERSION_MAJOR __GNUC__
# define RBIMPL_COMPILER_VERSION_MINOR __GNUC_MINOR__
# define RBIMPL_COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
#endif
#endif /* RBIMPL_COMPILER_IS_GCC_H */
include/ruby/internal/encoding/re.h 0000644 00000004356 15040330605 0013335 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_RE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_RE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate encodings of symbols.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Identical to rb_reg_new(), except it additionally takes an encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @param[in] enc Encoding of `ptr`.
* @param[in] opts Options e.g. ONIG_OPTION_MULTILINE.
* @exception rb_eRegexpError Failed to compile `ptr`.
* @return An allocated new instance of ::rb_cRegexp, of `enc` encoding,
* whose expression is compiled according to `ptr`.
*/
VALUE rb_enc_reg_new(const char *ptr, long len, rb_encoding *enc, int opts);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_RE_H */
include/ruby/internal/encoding/pathname.h 0000644 00000015420 15040330605 0014516 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_PATHNAME_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_PATHNAME_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate encodings of pathnames.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
* Returns a path component directly adjacent to the passed pointer.
*
* ```
* "/multi/byte/encoded/pathname.txt"
* ^ ^ ^
* | | +--- end
* | +--- @return
* +--- path
* ```
*
* @param[in] path Where to start scanning.
* @param[in] end End of the path string.
* @param[in] enc Encoding of the string.
* @return A pointer in the passed string where the next path component
* resides, or `end` if there is no next path component.
*/
char *rb_enc_path_next(const char *path, const char *end, rb_encoding *enc);
RBIMPL_ATTR_NONNULL(())
/**
* Seeks for non-prefix part of a pathname. This can be a no-op when the OS
* has no such concept like a path prefix. But there are OSes where path
* prefixes do exist.
*
* ```
* "C:\multi\byte\encoded\pathname.txt"
* ^ ^ ^
* | | +--- end
* | +--- @return
* +--- path
* ```
*
* @param[in] path Where to start scanning.
* @param[in] end End of the path string.
* @param[in] enc Encoding of the string.
* @return A pointer in the passed string where non-prefix part starts, or
* `path` if the OS does not have path prefix.
*/
char *rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc);
RBIMPL_ATTR_NONNULL(())
/**
* Returns the last path component.
*
* ```
* "/multi/byte/encoded/pathname.txt"
* ^ ^ ^
* | | +--- end
* | +--- @return
* +--- path
* ```
*
* @param[in] path Where to start scanning.
* @param[in] end End of the path string.
* @param[in] enc Encoding of the string.
* @return A pointer in the passed string where the last path component
* resides, or `end` if there is no more path component.
*/
char *rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc);
RBIMPL_ATTR_NONNULL(())
/**
* This just returns the passed end basically. It makes difference in case the
* passed string ends with tons of path separators like the following:
*
* ```
* "/path/that/ends/with/lots/of/slashes//////////////"
* ^ ^ ^
* | | +--- end
* | +--- @return
* +--- path
* ```
*
* @param[in] path Where to start scanning.
* @param[in] end End of the path string.
* @param[in] enc Encoding of the string.
* @return A pointer in the passed string where the trailing path
* separators start, or `end` if there is no trailing path
* separators.
*
* @internal
*
* It seems this function was introduced to mimic what POSIX says about
* `basename(3)`.
*/
char *rb_enc_path_end(const char *path, const char *end, rb_encoding *enc);
RBIMPL_ATTR_NONNULL((1, 4))
/**
* Our own encoding-aware version of `basename(3)`. Normally, this function
* returns the last path component of the given name. However in case the
* passed name ends with a path separator, it returns the name of the
* directory, not the last (empty) component. Also if the passed name is a
* root directory, it returns that root directory. Note however that Windows
* filesystem have drive letters, which this function does not return.
*
* @param[in] name Target path.
* @param[out] baselen Return buffer.
* @param[in,out] alllen Number of bytes of `name`.
* @param[enc] enc Encoding of `name`.
* @return The rightmost component of `name`.
* @post `baselen`, if passed, is updated to be the number of bytes
* of the returned basename.
* @post `alllen`, if passed, is updated to be the number of bytes of
* strings not considered as the basename.
*/
const char *ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encoding *enc);
RBIMPL_ATTR_NONNULL((1, 3))
/**
* Our own encoding-aware version of `extname`. This function first applies
* rb_enc_path_last_separator() to the passed name and only concerns its return
* value (ignores any parent directories). This function returns complicated
* results:
*
* ```CXX
* auto path = "...";
* auto len = strlen(path);
* auto ret = ruby_enc_find_extname(path, &len, rb_ascii8bit_encoding());
*
* switch(len) {
* case 0:
* if (ret == 0) {
* // `path` is a file without extensions.
* }
* else {
* // `path` is a dotfile.
* // `ret` is the file's name.
* }
* break;
*
* case 1:
* // `path` _ends_ with a dot.
* // `ret` is that dot.
* break;
*
* default:
* // `path` has an extension.
* // `ret` is that extension.
* }
* ```
*
* @param[in] name Target path.
* @param[in,out] len Number of bytes of `name`.
* @param[in] enc Encoding of `name`.
* @return See above.
* @post `len`, if passed, is updated (see above).
*/
const char *ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_PATHNAME_H */
include/ruby/internal/encoding/encoding.h 0000644 00000110664 15040330605 0014515 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_ENCODING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_ENCODING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines ::rb_encoding
*/
#include "ruby/oniguruma.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/fl_type.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* `Encoding` class.
*
* @ingroup object
*/
RUBY_EXTERN VALUE rb_cEncoding;
/**
* @private
*
* Bit constants used when embedding encodings into ::RBasic::flags. Extension
* libraries must not bother such things.
*/
enum ruby_encoding_consts {
/** Max possible number of embeddable encodings. */
RUBY_ENCODING_INLINE_MAX = 127,
/** Where inline encodings reside. */
RUBY_ENCODING_SHIFT = (RUBY_FL_USHIFT+10),
/** Bits we use to store inline encodings. */
RUBY_ENCODING_MASK = (RUBY_ENCODING_INLINE_MAX<<RUBY_ENCODING_SHIFT
/* RUBY_FL_USER10..RUBY_FL_USER16 */),
/** Max possible length of an encoding name. */
RUBY_ENCODING_MAXNAMELEN = 42
};
#define ENCODING_INLINE_MAX RUBY_ENCODING_INLINE_MAX /**< @old{RUBY_ENCODING_INLINE_MAX} */
#define ENCODING_SHIFT RUBY_ENCODING_SHIFT /**< @old{RUBY_ENCODING_SHIFT} */
#define ENCODING_MASK RUBY_ENCODING_MASK /**< @old{RUBY_ENCODING_MASK} */
/**
* Destructively assigns the passed encoding to the passed object. The object
* must be capable of having inline encoding. Using this macro needs deep
* understanding of bit level object binary layout.
*
* @param[out] obj Target object to modify.
* @param[in] ecindex Encoding in encindex format.
* @post `obj`'s encoding is `encindex`.
*/
static inline void
RB_ENCODING_SET_INLINED(VALUE obj, int encindex)
{
VALUE f = /* upcast */ encindex;
f <<= RUBY_ENCODING_SHIFT;
RB_FL_UNSET_RAW(obj, RUBY_ENCODING_MASK);
RB_FL_SET_RAW(obj, f);
}
/**
* Queries the encoding of the passed object. The encoding must be smaller
* than ::RUBY_ENCODING_INLINE_MAX, which means you have some assumption on the
* return value. This means the API is for internal use only.
*
* @param[in] obj Target object.
* @return `obj`'s encoding index.
*/
static inline int
RB_ENCODING_GET_INLINED(VALUE obj)
{
VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT;
return RBIMPL_CAST((int)ret);
}
#define ENCODING_SET_INLINED(obj,i) RB_ENCODING_SET_INLINED(obj,i) /**< @old{RB_ENCODING_SET_INLINED} */
#define ENCODING_SET(obj,i) RB_ENCODING_SET(obj,i) /**< @old{RB_ENCODING_SET} */
#define ENCODING_GET_INLINED(obj) RB_ENCODING_GET_INLINED(obj) /**< @old{RB_ENCODING_GET_INLINED} */
#define ENCODING_GET(obj) RB_ENCODING_GET(obj) /**< @old{RB_ENCODING_GET} */
#define ENCODING_IS_ASCII8BIT(obj) RB_ENCODING_IS_ASCII8BIT(obj) /**< @old{RB_ENCODING_IS_ASCII8BIT} */
#define ENCODING_MAXNAMELEN RUBY_ENCODING_MAXNAMELEN /**< @old{RUBY_ENCODING_MAXNAMELEN} */
/**
* The type of encoding. Our design here is we take Oniguruma/Onigmo's
* multilingualisation schema as our base data structure.
*/
typedef const OnigEncodingType rb_encoding;
RBIMPL_ATTR_NOALIAS()
/**
* Converts a character option to its encoding. It only supports a very
* limited set of Japanese encodings due to its Japanese origin. Ruby still
* has this in-core for backwards compatibility. But new codes must not bother
* such concept like one-character encoding option. Consider deprecated in
* practice.
*
* @param[in] c One of `['n', 'e', 's', 'u', 'i', 'x', 'm']`.
* @param[out] option Return buffer.
* @param[out] kcode Return buffer.
* @retval 1 `c` understood properly.
* @retval 0 `c` is not understood.
* @post `option` is a ::OnigOptionType.
* @post `kcode` is an enum `ruby_preserved_encindex`.
*
* @internal
*
* `kcode` is opaque because `ruby_preserved_encindex` is not visible from
* extension libraries. But who cares?
*/
int rb_char_to_option_kcode(int c, int *option, int *kcode);
/**
* Creates a new encoding, using the passed one as a template.
*
* @param[in] name Name of the creating encoding.
* @param[in] src Template.
* @exception rb_eArgError Duplicated or malformed `name`.
* @return Replicated new encoding's index.
* @post Encoding named `name` is created as a copy of `src`, whose index
* is the return value.
*
* @internal
*
* `name` can be `NULL`, but that just raises an exception. OTOH it seems no
* sanity check is done against `src`...?
*/
int rb_enc_replicate(const char *name, rb_encoding *src);
/**
* Creates a new "dummy" encoding. Roughly speaking, an encoding is dummy when
* it is stateful. Notable example of dummy encoding are those defined in
* ISO/IEC 2022
*
* @param[in] name Name of the creating encoding.
* @exception rb_eArgError Duplicated or malformed `name`.
* @return New dummy encoding's index.
* @post Encoding named `name` is created, whose index is the return
* value.
*/
int rb_define_dummy_encoding(const char *name);
RBIMPL_ATTR_PURE()
/**
* Queries if the passed encoding is dummy.
*
* @param[in] enc Encoding in question.
* @retval 1 It is.
* @retval 0 It isn't.
*/
int rb_enc_dummy_p(rb_encoding *enc);
RBIMPL_ATTR_PURE()
/**
* Queries the index of the encoding. An encoding's index is a Ruby-local
* concept. It is a (sequential) number assigned to each encoding.
*
* @param[in] enc Encoding in question.
* @return Its index.
* @note You can pass null pointers to this function. It is equivalent
* to rb_usascii_encindex() then.
*/
int rb_enc_to_index(rb_encoding *enc);
/**
* Queries the index of the encoding of the passed object, if any.
*
* @param[in] obj Object in question.
* @retval -1 `obj` is incapable of having an encoding.
* @retval otherwise `obj`'s encoding's index.
*/
int rb_enc_get_index(VALUE obj);
/**
* @alias{rb_enc_get_index}
*
* @internal
*
* Implementation wise this is not a verbatim alias of rb_enc_get_index(). But
* the API is consistent. Don't bother.
*/
static inline int
RB_ENCODING_GET(VALUE obj)
{
int encindex = RB_ENCODING_GET_INLINED(obj);
if (encindex == RUBY_ENCODING_INLINE_MAX) {
return rb_enc_get_index(obj);
}
else {
return encindex;
}
}
/**
* Destructively assigns an encoding (via its index) to an object.
*
* @param[out] obj Object in question.
* @param[in] encindex An encoding index.
* @exception rb_eFrozenError `obj` is frozen.
* @exception rb_eArgError `obj` is incapable of having an encoding.
* @exception rb_eEncodingError `encindex` is out of bounds.
* @exception rb_eLoadError Failed to load the encoding.
*/
void rb_enc_set_index(VALUE obj, int encindex);
/** @alias{rb_enc_set_index} */
static inline void
RB_ENCODING_SET(VALUE obj, int encindex)
{
rb_enc_set_index(obj, encindex);
}
/**
* This is #RB_ENCODING_SET + RB_ENC_CODERANGE_SET combo. The object must be
* capable of having inline encoding. Using this macro needs deep
* understanding of bit level object binary layout.
*
* @param[out] obj Target object.
* @param[in] encindex Encoding in encindex format.
* @param[in] cr An enum ::ruby_coderange_type.
* @post `obj`'s encoding is `encindex`.
* @post `obj`'s code range is `cr`.
*/
static inline void
RB_ENCODING_CODERANGE_SET(VALUE obj, int encindex, enum ruby_coderange_type cr)
{
RB_ENCODING_SET(obj, encindex);
RB_ENC_CODERANGE_SET(obj, cr);
}
RBIMPL_ATTR_PURE()
/**
* Queries if the passed object can have its encoding.
*
* @param[in] obj Object in question.
* @retval 1 It can.
* @retval 0 It cannot.
*/
int rb_enc_capable(VALUE obj);
/**
* Queries the index of the encoding.
*
* @param[in] name Name of the encoding to find.
* @exception rb_eArgError No such encoding named `name`.
* @retval -1 `name` exists, but unable to load.
* @retval otherwise Index of encoding named `name`.
*/
int rb_enc_find_index(const char *name);
/**
* Registers an "alias" name. In the wild, an encoding can be called using
* multiple names. For instance an encoding known as `"CP932"` is also called
* `"SJIS"` on occasions. This API registers such relationships.
*
* @param[in] alias New name.
* @param[in] orig Old name.
* @exception rb_eArgError `alias` is duplicated or malformed.
* @retval -1 Failed to load `orig`.
* @retval otherwise The index of `orig` and `alias`.
* @post `alias` is a synonym of `orig`. They refer to the identical
* encoding.
*/
int rb_enc_alias(const char *alias, const char *orig);
/**
* Obtains a encoding index from a wider range of objects (than
* rb_enc_find_index()).
*
* @param[in] obj An ::rb_cEncoding, or its name in ::rb_cString.
* @retval -1 `obj` is unexpected type/contents.
* @retval otherwise Index corresponding to `obj`.
*/
int rb_to_encoding_index(VALUE obj);
/**
* Identical to rb_find_encoding(), except it raises an exception instead of
* returning NULL.
*
* @param[in] obj An ::rb_cEncoding, or its name in ::rb_cString.
* @exception rb_eTypeError `obj` is neither ::rb_cEncoding nor ::rb_cString.
* @exception rb_eArgError `obj` is an unknown encoding name.
* @return Encoding of `obj`.
*/
rb_encoding *rb_to_encoding(VALUE obj);
/**
* Identical to rb_to_encoding_index(), except the return type.
*
* @param[in] obj An ::rb_cEncoding, or its name in ::rb_cString.
* @exception rb_eTypeError `obj` is neither ::rb_cEncoding nor ::rb_cString.
* @retval NULL No such encoding.
* @return otherwise Encoding of `obj`.
*/
rb_encoding *rb_find_encoding(VALUE obj);
/**
* Identical to rb_enc_get_index(), except the return type.
*
* @param[in] obj Object in question.
* @retval NULL Obj is incapable of having an encoding.
* @retval otherwise `obj`'s encoding.
*/
rb_encoding *rb_enc_get(VALUE obj);
/**
* Look for the "common" encoding between the two. One character can or cannot
* be expressed depending on an encoding. This function finds the super-set of
* encodings that satisfy contents of both arguments. If that is impossible
* returns NULL.
*
* @param[in] str1 An object.
* @param[in] str2 Another object.
* @retval NULL No encoding can satisfy both at once.
* @retval otherwise Common encoding between the two.
* @note Arguments can be non-string, e.g. Regexp.
*/
rb_encoding *rb_enc_compatible(VALUE str1, VALUE str2);
/**
* Identical to rb_enc_compatible(), except it raises an exception instead of
* returning NULL.
*
* @param[in] str1 An object.
* @param[in] str2 Another object.
* @exception rb_eEncCompatError No encoding can satisfy both.
* @return Common encoding between the two.
* @note Arguments can be non-string, e.g. Regexp.
*/
rb_encoding *rb_enc_check(VALUE str1,VALUE str2);
/**
* Identical to rb_enc_set_index(), except it additionally does contents fix-up
* depending on the passed object. It for instance changes the byte length of
* terminating `U+0000` according to the passed encoding.
*
* @param[out] obj Object in question.
* @param[in] encindex An encoding index.
* @exception rb_eFrozenError `obj` is frozen.
* @exception rb_eArgError `obj` is incapable of having an encoding.
* @exception rb_eEncodingError `encindex` is out of bounds.
* @exception rb_eLoadError Failed to load the encoding.
* @return The passed `obj`.
* @post `obj`'s contents might be fixed according to `encindex`.
*/
VALUE rb_enc_associate_index(VALUE obj, int encindex);
/**
* Identical to rb_enc_associate_index(), except it takes an encoding itself
* instead of its index.
*
* @param[out] obj Object in question.
* @param[in] enc An encoding.
* @exception rb_eFrozenError `obj` is frozen.
* @exception rb_eArgError `obj` is incapable of having an encoding.
* @return The passed `obj`.
* @post `obj`'s contents might be fixed according to `enc`.
*/
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc);
/**
* Destructively copies the encoding of the latter object to that of former
* one. It can also be seen as a routine identical to
* rb_enc_associate_index(), except it takes an object's encoding instead of an
* encoding's index.
*
* @param[out] dst Object to modify.
* @param[in] src Object to reference.
* @exception rb_eFrozenError `dst` is frozen.
* @exception rb_eArgError `dst` is incapable of having an encoding.
* @exception rb_eEncodingError `src` is incapable of having an encoding.
* @post `dst`'s encoding is that of `src`'s.
*/
void rb_enc_copy(VALUE dst, VALUE src);
/**
* Identical to rb_find_encoding(), except it takes an encoding index instead
* of a Ruby object.
*
* @param[in] idx An encoding index.
* @retval NULL No such encoding.
* @retval otherwise An encoding whose index is `idx`.
*/
rb_encoding *rb_enc_from_index(int idx);
/**
* Identical to rb_find_encoding(), except it takes a C's string instead of
* Ruby's.
*
* @param[in] name Name of the encoding to query.
* @retval NULL No such encoding.
* @retval otherwise An encoding whose index is `idx`.
*/
rb_encoding *rb_enc_find(const char *name);
/**
* Queries the (canonical) name of the passed encoding.
*
* @param[in] enc An encoding.
* @return Its name.
*/
static inline const char *
rb_enc_name(rb_encoding *enc)
{
return enc->name;
}
/**
* Queries the minimum number of bytes that the passed encoding needs to
* represent a character. For ASCII and compatible encodings this is typically
* 1. There are however encodings whose minimum is not 1; they are
* historically called wide characters.
*
* @param[in] enc An encoding.
* @return Its least possible number of bytes except 0.
*/
static inline int
rb_enc_mbminlen(rb_encoding *enc)
{
return enc->min_enc_len;
}
/**
* Queries the maximum number of bytes that the passed encoding needs to
* represent a character. Fixed-width encodings have the same value for this
* one and #rb_enc_mbminlen. However there are variable-width encodings.
* UTF-8, for instance, takes from 1 up to 6 bytes.
*
* @param[in] enc An encoding.
* @return Its maximum possible number of bytes of a character.
*/
static inline int
rb_enc_mbmaxlen(rb_encoding *enc)
{
return enc->max_enc_len;
}
/**
* Queries the number of bytes of the character at the passed pointer.
*
* @param[in] p Pointer to a character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] enc Encoding of the string.
* @return If the character at `p` does not end until `e`, number of bytes
* between `p` and `e`. Otherwise the number of bytes that the
* character at `p` is encoded.
*
* @internal
*
* Strictly speaking there are chances when `p` points to a middle byte of a
* wide character. This function returns "the number of bytes from `p` to
* nearest of either `e` or the next character boundary", if you go strict.
*/
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc);
/**
* Identical to rb_enc_mbclen() unless the character at `p` overruns `e`. That
* can happen for instance when you read from a socket and its partial read
* cuts a wide character in-between. In those situations this function
* "estimates" theoretical length of the character in question. Typically it
* tends to be possible to know how many bytes a character needs before
* actually reaching its end; for instance UTF-8 encodes a character's length
* in the first byte of it. This function returns that info.
*
* @note This implies that the string is not broken.
*
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] enc Encoding of the string.
* @return Number of bytes of character at `p`, measured or estimated.
*/
int rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc);
/**
* Queries the number of bytes of the character at the passed pointer. This
* function returns 3 different types of information:
*
* ```CXX
* auto n = rb_enc_precise_mbclen(p, q, r);
*
* if (ONIGENC_MBCLEN_CHARFOUND_P(n)) {
* // Character found. Normal return.
* auto found_length = ONIGENC_MBCLEN_CHARFOUND_LEN(n);
* }
* else if (ONIGENC_MBCLEN_NEEDMORE_P(n)) {
* // Character overruns past `q`; needs more.
* auto requested_length = ONIGENC_MBCLEN_NEEDMORE_LEN(n);
* }
* else {
* // `p` is broken.
* assert(ONIGENC_MBCLEN_INVALID_P(n));
* }
* ```
*
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] enc Encoding of the string.
* @return Encoded read/needed number of bytes (see above).
*/
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc);
#define MBCLEN_CHARFOUND_P(ret) ONIGENC_MBCLEN_CHARFOUND_P(ret) /**< @old{ONIGENC_MBCLEN_CHARFOUND_P} */
#define MBCLEN_CHARFOUND_LEN(ret) ONIGENC_MBCLEN_CHARFOUND_LEN(ret) /**< @old{ONIGENC_MBCLEN_CHARFOUND_LEN} */
#define MBCLEN_INVALID_P(ret) ONIGENC_MBCLEN_INVALID_P(ret) /**< @old{ONIGENC_MBCLEN_INVALID_P} */
#define MBCLEN_NEEDMORE_P(ret) ONIGENC_MBCLEN_NEEDMORE_P(ret) /**< @old{ONIGENC_MBCLEN_NEEDMORE_P} */
#define MBCLEN_NEEDMORE_LEN(ret) ONIGENC_MBCLEN_NEEDMORE_LEN(ret) /**< @old{ONIGENC_MBCLEN_NEEDMORE_LEN} */
/**
* Queries the code point of character pointed by the passed pointer. If that
* code point is included in ASCII that code point is returned. Otherwise -1.
* This can be different from just looking at the first byte. For instance it
* reads 2 bytes in case of UTF-16BE.
*
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] len Return buffer.
* @param[in] enc Encoding of the string.
* @retval -1 The character at `p` is not i ASCII.
* @retval otherwise A code point of the character at `p`.
* @post `len` (if set) is the number of bytes of `p`.
*/
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc);
/**
* Queries the code point of character pointed by the passed pointer.
* Exceptions happen in case of broken input.
*
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] len Return buffer.
* @param[in] enc Encoding of the string.
* @exception rb_eArgError `p` is broken.
* @return Code point of the character pointed by `p`.
* @post `len` (if set) is the number of bytes of `p`.
*/
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len, rb_encoding *enc);
/**
* Queries the code point of character pointed by the passed pointer.
* Exceptions happen in case of broken input.
*
* @deprecated Use rb_enc_codepoint_len() instead.
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] enc Encoding of the string.
* @exception rb_eArgError `p` is broken.
* @return Code point of the character pointed by `p`.
*
* @internal
*
* @matz says in commit 91e5ba1cb865a2385d3e1cbfacd824496898e098 that the line
* below is a "prototype for obsolete function". However even today there
* still are some use cases of it throughout our repository. It seems it has
* its own niche.
*/
static inline unsigned int
rb_enc_codepoint(const char *p, const char *e, rb_encoding *enc)
{
return rb_enc_codepoint_len(p, e, 0, enc);
/* ^^^
* This can be `NULL` in C, `nullptr` in C++, and `0` for both.
* We choose the most portable one here.
*/
}
/**
* Identical to rb_enc_codepoint(), except it assumes the passed character is
* not broken.
*
* @param[in] p Pointer to the character's first byte.
* @param[in] e End of the string that has `p`.
* @param[in] enc Encoding of the string.
* @return Code point of the character pointed by `p`.
*/
static inline OnigCodePoint
rb_enc_mbc_to_codepoint(const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
return ONIGENC_MBC_TO_CODE(enc, up, ue);
}
/**
* Queries the number of bytes requested to represent the passed code point
* using the passed encoding.
*
* @param[in] code Code point in question.
* @param[in] enc Encoding to convert the code into a byte sequence.
* @exception rb_eArgError `enc` does not glean `code`.
* @return Number of bytes requested to represent `code` using `enc`.
*/
int rb_enc_codelen(int code, rb_encoding *enc);
/**
* Identical to rb_enc_codelen(), except it returns 0 for invalid code points.
*
* @param[in] c Code point in question.
* @param[in] enc Encoding to convert `c` into a byte sequence.
* @retval 0 `c` is invalid.
* @return otherwise Number of bytes needed for `enc` to encode `c`.
*/
static inline int
rb_enc_code_to_mbclen(int c, rb_encoding *enc)
{
OnigCodePoint uc = RBIMPL_CAST((OnigCodePoint)c);
return ONIGENC_CODE_TO_MBCLEN(enc, uc);
}
/**
* Identical to rb_enc_uint_chr(), except it writes back to the passed buffer
* instead of allocating one.
*
* @param[in] c Code point.
* @param[out] buf Return buffer.
* @param[in] enc Target encoding scheme.
* @retval <= 0 `c` is invalid in `enc`.
* @return otherwise Number of bytes written to `buf`.
* @post `c` is encoded according to `enc`, then written to `buf`.
*
* @internal
*
* The second argument must be typed. But its current usages prevent us from
* being any stricter than this. :FIXME:
*/
static inline int
rb_enc_mbcput(unsigned int c, void *buf, rb_encoding *enc)
{
OnigCodePoint uc = RBIMPL_CAST((OnigCodePoint)c);
OnigUChar *ubuf = RBIMPL_CAST((OnigUChar *)buf);
return ONIGENC_CODE_TO_MBC(enc, uc, ubuf);
}
/**
* Queries the previous (left) character.
*
* @param[in] s Start of the string.
* @param[in] p Pointer to a character.
* @param[in] e End of the string.
* @param[in] enc Encoding.
* @retval NULL No previous character.
* @retval otherwise Pointer to the head of the previous character.
*/
static inline char *
rb_enc_prev_char(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_prev_char_head(enc, us, up, ue);
return RBIMPL_CAST((char *)ur);
}
/**
* Queries the left boundary of a character. This function takes a pointer
* that is not necessarily a head of a character, and searches for its head.
*
* @param[in] s Start of the string.
* @param[in] p Pointer to a possibly-middle of a character.
* @param[in] e End of the string.
* @param[in] enc Encoding.
* @return Pointer to the head of the character that contains `p`.
*/
static inline char *
rb_enc_left_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_left_adjust_char_head(enc, us, up, ue);
return RBIMPL_CAST((char *)ur);
}
/**
* Queries the right boundary of a character. This function takes a pointer
* that is not necessarily a head of a character, and searches for its tail.
*
* @param[in] s Start of the string.
* @param[in] p Pointer to a possibly-middle of a character.
* @param[in] e End of the string.
* @param[in] enc Encoding.
* @return Pointer to the end of the character that contains `p`.
*/
static inline char *
rb_enc_right_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
OnigUChar *ur = onigenc_get_right_adjust_char_head(enc, us, up, ue);
return RBIMPL_CAST((char *)ur);
}
/**
* Scans the string backwards for n characters.
*
* @param[in] s Start of the string.
* @param[in] p Pointer to a character.
* @param[in] e End of the string.
* @param[in] n Steps.
* @param[in] enc Encoding.
* @retval NULL There are no `n` characters left.
* @retval otherwise Pointer to `n` character before `p`.
*/
static inline char *
rb_enc_step_back(const char *s, const char *p, const char *e, int n, rb_encoding *enc)
{
const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
const OnigUChar *ur = onigenc_step_back(enc, us, up, ue, n);
return RBIMPL_CAST((char *)ur);
}
/**
* @private
*
* This is an implementation detail of rb_enc_asciicompat(). People don't use
* it directly. Just always use rb_enc_asciicompat().
*
* @param[in] enc Encoding in question.
* @retval 1 It is ASCII compatible.
* @retval 0 It isn't.
*/
static inline int
rb_enc_asciicompat_inline(rb_encoding *enc)
{
return rb_enc_mbminlen(enc)==1 && !rb_enc_dummy_p(enc);
}
/**
* Queries if the passed encoding is _in some sense_ compatible with ASCII.
* The concept of ASCII compatibility is nuanced, and private to our
* implementation. For instance SJIS is ASCII compatible to us, despite their
* having different characters at code point `0x5C`. This is based on some
* practical consideration that Japanese people confuses SJIS to be "upper
* compatible" with ASCII (which is in fact a wrong idea, but we just don't go
* strict here). An example of ASCII incompatible encoding is UTF-16. UTF-16
* shares code points with ASCII, but employs a completely different encoding
* scheme.
*
* @param[in] enc Encoding in question.
* @retval 0 It is incompatible.
* @retval 1 It is compatible.
*/
static inline bool
rb_enc_asciicompat(rb_encoding *enc)
{
if (rb_enc_mbminlen(enc) != 1) {
return false;
}
else if (rb_enc_dummy_p(enc)) {
return false;
}
else {
return true;
}
}
/**
* Queries if the passed string is in an ASCII-compatible encoding.
*
* @param[in] str A Ruby's string to query.
* @retval 0 `str` is not a String, or an ASCII-incompatible string.
* @retval 1 Otherwise.
*/
static inline bool
rb_enc_str_asciicompat_p(VALUE str)
{
rb_encoding *enc = rb_enc_get(str);
return rb_enc_asciicompat(enc);
}
/**
* Queries the Ruby-level counterpart instance of ::rb_cEncoding that
* corresponds to the passed encoding.
*
* @param[in] enc An encoding
* @retval RUBY_Qnil `enc` is a null pointer.
* @retval otherwise An instance of ::rb_cEncoding.
*/
VALUE rb_enc_from_encoding(rb_encoding *enc);
RBIMPL_ATTR_PURE()
/**
* Queries if the passed encoding is either one of UTF-8/16/32.
*
* @note It does not take UTF-7, which we actually support, into account.
*
* @param[in] enc Encoding in question.
* @retval 0 It is not a Unicode variant.
* @retval otherwise It is.
*
* @internal
*
* In reality it returns 1/0, but the value is abstracted as
* `ONIGENC_FLAG_UNICODE`.
*/
int rb_enc_unicode_p(rb_encoding *enc);
RBIMPL_ATTR_RETURNS_NONNULL()
/**
* Queries the encoding that represents ASCII-8BIT a.k.a. binary.
*
* @return The encoding that represents ASCII-8BIT.
*
* @internal
*
* This can not return NULL once the process properly boots up.
*/
rb_encoding *rb_ascii8bit_encoding(void);
RBIMPL_ATTR_RETURNS_NONNULL()
/**
* Queries the encoding that represents UTF-8.
*
* @return The encoding that represents UTF-8.
*
* @internal
*
* This can not return NULL once the process properly boots up.
*/
rb_encoding *rb_utf8_encoding(void);
RBIMPL_ATTR_RETURNS_NONNULL()
/**
* Queries the encoding that represents US-ASCII.
*
* @return The encoding that represents US-ASCII.
*
* @internal
*
* This can not return NULL once the process properly boots up.
*/
rb_encoding *rb_usascii_encoding(void);
/**
* Queries the encoding that represents the current locale.
*
* @return The encoding that represents the process' locale.
*
* @internal
*
* This is dynamic. If you change the process' locale by e.g. calling
* `setlocale(3)`, that should also change the return value of this function.
*
* There is no official way for Ruby scripts to manipulate locales, though.
*/
rb_encoding *rb_locale_encoding(void);
/**
* Queries the "filesystem" encoding. This is the encoding that ruby expects
* info from the OS' file system are in. This affects for instance return
* value of rb_dir_getwd(). Most notably on Windows it can be an alias of OS
* codepage. Most notably on Linux users can set this via default external
* encoding.
*
* @return The "filesystem" encoding.
*/
rb_encoding *rb_filesystem_encoding(void);
/**
* Queries the "default external" encoding. This is used to interact with
* outer-process things such as File. Though not recommended, you can set this
* using rb_enc_set_default_external().
*
* @return The "default external" encoding.
*/
rb_encoding *rb_default_external_encoding(void);
/**
* Queries the "default internal" encoding. This could be a null pointer.
* Otherwise, outer-process info are transcoded from default external encoding
* to this one during reading from an IO.
*
* @return The "default internal" encoding (if any).
*/
rb_encoding *rb_default_internal_encoding(void);
#ifndef rb_ascii8bit_encindex
RBIMPL_ATTR_CONST()
/**
* Identical to rb_ascii8bit_encoding(), except it returns the encoding's index
* instead of the encoding itself.
*
* @return The index of encoding of ASCII-8BIT.
*
* @internal
*
* This happens to be 0.
*/
int rb_ascii8bit_encindex(void);
#endif
/**
* Queries if the passed object is in ascii 8bit (== binary) encoding. The
* object must be capable of having inline encoding. Using this macro needs
* deep understanding of bit level object binary layout.
*
* @param[in] obj An object to check.
* @retval 1 It is.
* @retval 0 It isn't.
*/
static inline bool
RB_ENCODING_IS_ASCII8BIT(VALUE obj)
{
return RB_ENCODING_GET_INLINED(obj) == rb_ascii8bit_encindex();
}
#ifndef rb_utf8_encindex
RBIMPL_ATTR_CONST()
/**
* Identical to rb_utf8_encoding(), except it returns the encoding's index
* instead of the encoding itself.
*
* @return The index of encoding of UTF-8.
*/
int rb_utf8_encindex(void);
#endif
#ifndef rb_usascii_encindex
RBIMPL_ATTR_CONST()
/**
* Identical to rb_usascii_encoding(), except it returns the encoding's index
* instead of the encoding itself.
*
* @return The index of encoding of UTF-8.
*/
int rb_usascii_encindex(void);
#endif
/**
* Identical to rb_locale_encoding(), except it returns the encoding's index
* instead of the encoding itself.
*
* @return The index of the locale encoding.
*/
int rb_locale_encindex(void);
/**
* Identical to rb_filesystem_encoding(), except it returns the encoding's
* index instead of the encoding itself.
*
* @return The index of the filesystem encoding.
*/
int rb_filesystem_encindex(void);
/**
* Identical to rb_default_external_encoding(), except it returns the
* Ruby-level counterpart instance of ::rb_cEncoding that corresponds to the
* default external encoding.
*
* @return An instance of ::rb_cEncoding of default external.
*/
VALUE rb_enc_default_external(void);
/**
* Identical to rb_default_internal_encoding(), except it returns the
* Ruby-level counterpart instance of ::rb_cEncoding that corresponds to the
* default internal encoding.
*
* @return An instance of ::rb_cEncoding of default internal.
*/
VALUE rb_enc_default_internal(void);
/**
* Destructively assigns the passed encoding as the default external encoding.
* You should not use this API. It has process-global side effects. Also it
* doesn't change encodings of strings that have already been read.
*
* @param[in] encoding Ruby level encoding.
* @exception rb_eArgError `encoding` is ::RUBY_Qnil.
* @post The default external encoding is `encoding`.
*/
void rb_enc_set_default_external(VALUE encoding);
/**
* Destructively assigns the passed encoding as the default internal encoding.
* You should not use this API. It has process-global side effects. Also it
* doesn't change encodings of strings that have already been read.
*
* @param[in] encoding Ruby level encoding.
* @post The default internal encoding is `encoding`.
* @note Unlike rb_enc_set_default_external() you can pass ::RUBY_Qnil.
*/
void rb_enc_set_default_internal(VALUE encoding);
/**
* Returns a platform-depended "charmap" of the current locale. This
* information is called a "Codeset name" in IEEE 1003.1 section 13
* (`<langinfo.h>`). This is a very low-level API. The return value can have
* no corresponding encoding when passed to rb_find_encoding().
*
* @param[in] klass Ignored for no reason (why...)
* @return The low-level locale charmap, in Ruby's String.
*/
VALUE rb_locale_charmap(VALUE klass);
RBIMPL_SYMBOL_EXPORT_END()
/** @cond INTERNAL_MACRO */
#define RB_ENCODING_GET RB_ENCODING_GET
#define RB_ENCODING_GET_INLINED RB_ENCODING_GET_INLINED
#define RB_ENCODING_IS_ASCII8BIT RB_ENCODING_IS_ASCII8BIT
#define RB_ENCODING_SET RB_ENCODING_SET
#define RB_ENCODING_SET_INLINED RB_ENCODING_SET_INLINED
#define rb_enc_asciicompat rb_enc_asciicompat
#define rb_enc_code_to_mbclen rb_enc_code_to_mbclen
#define rb_enc_codepoint rb_enc_codepoint
#define rb_enc_left_char_head rb_enc_left_char_head
#define rb_enc_mbc_to_codepoint rb_enc_mbc_to_codepoint
#define rb_enc_mbcput rb_enc_mbcput
#define rb_enc_mbmaxlen rb_enc_mbmaxlen
#define rb_enc_mbminlen rb_enc_mbminlen
#define rb_enc_name rb_enc_name
#define rb_enc_prev_char rb_enc_prev_char
#define rb_enc_right_char_head rb_enc_right_char_head
#define rb_enc_step_back rb_enc_step_back
#define rb_enc_str_asciicompat_p rb_enc_str_asciicompat_p
/** @endcond */
#endif /* RUBY_INTERNAL_ENCODING_ENCODING_H */
include/ruby/internal/encoding/ctype.h 0000644 00000017527 15040330605 0014057 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_CTYPE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_CTYPE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to query chacater types.
*/
#include "ruby/onigmo.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Queries if the passed pointer points to a newline character. What is a
* newline and what is not depends on the passed encoding.
*
* @param[in] p Pointer to a possibly-middle of a character.
* @param[in] end End of the string.
* @param[in] enc Encoding.
* @retval false It isn't.
* @retval true It is.
*/
static inline bool
rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc)
{
OnigUChar *up = RBIMPL_CAST((OnigUChar *)p);
OnigUChar *ue = RBIMPL_CAST((OnigUChar *)e);
return ONIGENC_IS_MBC_NEWLINE(enc, up, ue);
}
/**
* Queries if the passed code point is of passed character type in the passed
* encoding. The "character type" here is a set of macros defined in onigmo.h,
* like `ONIGENC_CTYPE_PUNCT`.
*
* @param[in] c An `OnigCodePoint` value.
* @param[in] t An `OnigCtype` value.
* @param[in] enc A `rb_encoding*` value.
* @retval true `c` is of `t` in `enc`.
* @retval false Otherwise.
*/
static inline bool
rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc)
{
return ONIGENC_IS_CODE_CTYPE(enc, c, t);
}
/**
* Identical to rb_isascii(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval false `c` is out of range of ASCII character set in `enc`.
* @retval true Otherwise.
*
* @internal
*
* `enc` is ignored. This is at least an intentional implementation detail
* (not a bug). But there could be rooms for future extensions.
*/
static inline bool
rb_enc_isascii(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_ASCII(c);
}
/**
* Identical to rb_isalpha(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "ALPHA".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_ALPHA(enc, c);
}
/**
* Identical to rb_islower(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "LOWER".
* @retval false Otherwise.
*/
static inline bool
rb_enc_islower(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_LOWER(enc, c);
}
/**
* Identical to rb_isupper(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "UPPER".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isupper(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_UPPER(enc, c);
}
/**
* Identical to rb_iscntrl(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "CNTRL".
* @retval false Otherwise.
*/
static inline bool
rb_enc_iscntrl(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_CNTRL(enc, c);
}
/**
* Identical to rb_ispunct(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "PUNCT".
* @retval false Otherwise.
*/
static inline bool
rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_PUNCT(enc, c);
}
/**
* Identical to rb_isalnum(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "ANUM".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_ALNUM(enc, c);
}
/**
* Identical to rb_isprint(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "PRINT".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isprint(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_PRINT(enc, c);
}
/**
* Identical to rb_isspace(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "PRINT".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isspace(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_SPACE(enc, c);
}
/**
* Identical to rb_isdigit(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @retval true `enc` classifies `c` as "DIGIT".
* @retval false Otherwise.
*/
static inline bool
rb_enc_isdigit(OnigCodePoint c, rb_encoding *enc)
{
return ONIGENC_IS_CODE_DIGIT(enc, c);
}
RBIMPL_ATTR_CONST()
/**
* Identical to rb_toupper(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @return `c`'s (Ruby's definition of) upper case counterpart.
*
* @internal
*
* As `RBIMPL_ATTR_CONST` implies this function ignores `enc`.
*/
int rb_enc_toupper(int c, rb_encoding *enc);
RBIMPL_ATTR_CONST()
/**
* Identical to rb_tolower(), except it additionally takes an encoding.
*
* @param[in] c A code point.
* @param[in] enc An encoding.
* @return `c`'s (Ruby's definition of) lower case counterpart.
*
* @internal
*
* As `RBIMPL_ATTR_CONST` implies this function ignores `enc`.
*/
int rb_enc_tolower(int c, rb_encoding *enc);
RBIMPL_SYMBOL_EXPORT_END()
/** @cond INTERNAL_MACRO */
#define rb_enc_is_newline rb_enc_is_newline
#define rb_enc_isalnum rb_enc_isalnum
#define rb_enc_isalpha rb_enc_isalpha
#define rb_enc_isascii rb_enc_isascii
#define rb_enc_isctype rb_enc_isctype
#define rb_enc_isdigit rb_enc_isdigit
#define rb_enc_islower rb_enc_islower
#define rb_enc_isprint rb_enc_isprint
#define rb_enc_iscntrl rb_enc_iscntrl
#define rb_enc_ispunct rb_enc_ispunct
#define rb_enc_isspace rb_enc_isspace
#define rb_enc_isupper rb_enc_isupper
/** @endcond */
#endif /* RUBY_INTERNAL_ENCODING_CTYPE_H */
include/ruby/internal/encoding/string.h 0000644 00000036375 15040330605 0014243 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_STRING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_STRING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate encodings of strings.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/intern/string.h" /* rbimpl_strlen */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Identical to rb_enc_str_new(), except it additionally takes an encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eNoMemError Failed to allocate `len+1` bytes.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString, of `len` bytes length, of `enc`
* encoding, whose contents are verbatim copy of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
* @note `enc` can be a null pointer. It can also be seen as a routine
* identical to rb_usascii_str_new() then.
*/
VALUE rb_enc_str_new(const char *ptr, long len, rb_encoding *enc);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_enc_str_new(), except it assumes the passed pointer is a
* pointer to a C string. It can also be seen as a routine identical to
* rb_str_new_cstr(), except it additionally takes an encoding.
*
* @param[in] ptr A C string.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eNoMemError Failed to allocate memory.
* @return An instance of ::rb_cString, of `enc` encoding, whose contents
* are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
* @pre Because `ptr` is a C string it makes no sense for `enc` to be
* something like UTF-32.
* @note `enc` can be a null pointer. It can also be seen as a routine
* identical to rb_usascii_str_new_cstr() then.
*/
VALUE rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc);
/**
* Identical to rb_enc_str_new(), except it takes a C string literal. It can
* also be seen as a routine identical to rb_str_new_static(), except it
* additionally takes an encoding.
*
* @param[in] ptr A C string literal.
* @param[in] len `strlen(ptr)`.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eArgError `len` out of range of `size_t`.
* @pre `ptr` must be a C string constant.
* @return An instance of ::rb_cString, of `enc` encoding, whose backend
* storage is the passed C string literal.
* @warning It is a very bad idea to write to a C string literal (often
* immediate SEGV shall occur). Consider return values of this
* function be read-only.
* @note `enc` can be a null pointer. It can also be seen as a routine
* identical to rb_usascii_str_new_static() then.
*/
VALUE rb_enc_str_new_static(const char *ptr, long len, rb_encoding *enc);
/**
* Identical to rb_enc_str_new(), except it returns a "f"string. It can also
* be seen as a routine identical to rb_interned_str(), except it additionally
* takes an encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eArgError `len` is negative.
* @return A found or created instance of ::rb_cString, of `len` bytes
* length, of `enc` encoding, whose contents are identical to that
* of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
* @note `enc` can be a null pointer.
*/
VALUE rb_enc_interned_str(const char *ptr, long len, rb_encoding *enc);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_enc_str_new_cstr(), except it returns a "f"string. It can
* also be seen as a routine identical to rb_interned_str_cstr(), except it
* additionally takes an encoding.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] enc Encoding of `ptr`.
* @return A found or created instance of ::rb_cString of `enc` encoding,
* whose contents are identical to that of `ptr`.
* @pre At least `len` bytes of continuous memory region shall be
* accessible via `ptr`.
* @note `enc` can be a null pointer.
*/
VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc);
/**
* Counts the number of characters of the passed string, according to the
* passed encoding. This has to be complicated. The passed string could be
* invalid and/or broken. This routine would scan from the beginning til the
* end, byte by byte, to seek out character boundaries. Could be super slow.
*
* @param[in] head Leftmost pointer to the string.
* @param[in] tail Rightmost pointer to the string.
* @param[in] enc Encoding of the string.
* @return Number of characters exist in `head` .. `tail`. The definition
* of "character" depends on the passed `enc`.
*/
long rb_enc_strlen(const char *head, const char *tail, rb_encoding *enc);
/**
* Queries the n-th character. Like rb_enc_strlen() this function can be fast
* or slow depending on the contents. Don't expect characters to be uniformly
* distributed across the entire string.
*
* @param[in] head Leftmost pointer to the string.
* @param[in] tail Rightmost pointer to the string.
* @param[in] nth Requested index of characters.
* @param[in] enc Encoding of the string.
* @return Pointer to the first byte of the character that is `nth`
* character ahead of `head`, or `tail` if there is no such
* character (OOB etc). The definition of "character" depends on
* the passed `enc`.
*/
char *rb_enc_nth(const char *head, const char *tail, long nth, rb_encoding *enc);
/**
* Identical to rb_enc_get_index(), except the return type.
*
* @param[in] obj Object in question.
* @exception rb_eTypeError `obj` is incapable of having an encoding.
* @return `obj`'s encoding.
*/
VALUE rb_obj_encoding(VALUE obj);
/**
* Identical to rb_str_cat(), except it additionally takes an encoding.
*
* @param[out] str Destination object.
* @param[in] ptr Contents to append.
* @param[in] len Length of `src`, in bytes.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eArgError `len` is negative.
* @exception rb_eEncCompatError `enc` is not compatible with `str`.
* @return The passed `dst`.
* @post The contents of `ptr` is copied, transcoded into `dst`'s
* encoding, then pasted into `dst`'s end.
*/
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc);
/**
* Encodes the passed code point into a series of bytes.
*
* @param[in] code Code point.
* @param[in] enc Target encoding scheme.
* @exception rb_eRangeError `enc` does not glean `code`.
* @return An instance of ::rb_cString, of `enc` encoding, whose sole
* contents is `code` represented in `enc`.
* @note No way to encode code points bigger than UINT_MAX.
*
* @internal
*
* In other languages, APIs like this one could be seen as the primitive
* routines where encodings' "encode" feature are implemented. However in case
* of Ruby this is not the primitive one. We directly manipulate encoded
* strings. Encoding conversion routines transcode an encoded string directly
* to another one; not via a code point array.
*/
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc);
/**
* Identical to rb_external_str_new(), except it additionally takes an
* encoding. However the whole point of rb_external_str_new() is to encode a
* string into default external encoding. Being able to specify arbitrary
* encoding just ruins the designed purpose the function meseems.
*
* @param[in] ptr A memory region of `len` bytes length.
* @param[in] len Length of `ptr`, in bytes, not including the
* terminating NUL character.
* @param[in] enc Target encoding scheme.
* @exception rb_eArgError `len` is negative.
* @return An instance of ::rb_cString. In case encoding conversion from
* "default internal" to `enc` is fully defined over the given
* contents, then the return value is a string of `enc` encoding,
* whose contents are the converted ones. Otherwise the string is
* a junk.
* @warning It doesn't raise on a conversion failure and silently ends up in
* a corrupted output. You can know the failure by querying
* `valid_encoding?` of the result object.
*
* @internal
*
* @shyouhei has no idea why this one does not follow the naming convention
* that others obey. It seems to him that this should have been called
* `rb_enc_external_str_new`.
*/
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *enc);
/**
* Identical to rb_str_export(), except it additionally takes an encoding.
*
* @param[in] obj Target object.
* @param[in] enc Target encoding.
* @exception rb_eTypeError No implicit conversion to String.
* @return Converted ruby string of `enc` encoding.
*/
VALUE rb_str_export_to_enc(VALUE obj, rb_encoding *enc);
/**
* Encoding conversion main routine.
*
* @param[in] str String to convert.
* @param[in] from Source encoding.
* @param[in] to Destination encoding.
* @return A copy of `str`, with conversion from `from` to `to` applied.
* @note `from` can be a null pointer. `str`'s encoding is taken then.
* @note `to` can be a null pointer. No-op then.
*/
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to);
/**
* Identical to rb_str_conv_enc(), except it additionally takes IO encoder
* options. The extra arguments can be constructed using io_extract_modeenc()
* etc.
*
* @param[in] str String to convert.
* @param[in] from Source encoding.
* @param[in] to Destination encoding.
* @param[in] ecflags A set of enum ::ruby_econv_flag_type.
* @param[in] ecopts Optional hash.
* @return A copy of `str`, with conversion from `from` to `to` applied.
* @note `from` can be a null pointer. `str`'s encoding is taken then.
* @note `to` can be a null pointer. No-op then.
* @note `ecopts` can be ::RUBY_Qnil, which is equivalent to passing an
* empty hash.
*/
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts);
/**
* Scans the passed string to collect its code range. Because a Ruby's string
* is mutable, its contents change from time to time; so does its code range.
* A long-lived string tends to fall back to ::RUBY_ENC_CODERANGE_UNKNOWN.
* This API scans it and re-assigns a fine-grained code range constant.
*
* @param[out] str A string.
* @return An enum ::ruby_coderange_type.
*/
int rb_enc_str_coderange(VALUE str);
/**
* Scans the passed string until it finds something odd. Returns the number of
* bytes scanned. As the name implies this is suitable for repeated call. One
* of its application is `IO#readlines`. The method reads from its receiver's
* read buffer, maybe more than once, looking for newlines. But "newline" can
* be different among encodings. This API is used to detect broken contents to
* properly mark them as such.
*
* @param[in] str String to scan.
* @param[in] end End of `str`.
* @param[in] enc `str`'s encoding.
* @param[out] cr Return buffer.
* @return Distance between `str` and first such byte where broken.
* @post `cr` has the code range type.
*/
long rb_str_coderange_scan_restartable(const char *str, const char *end, rb_encoding *enc, int *cr);
/**
* Queries if the passed string is "ASCII only". An ASCII only string is a
* string who doesn't have any non-ASCII characters at all. This doesn't
* necessarily mean the string is in ASCII encoding. For instance a String of
* CP932 encoding can quite much be ASCII only, depending on its contents.
*
* @param[in] str String in question.
* @retval 1 It doesn't have non-ASCII characters.
* @retval 0 It has characters that are out of ASCII.
*/
int rb_enc_str_asciionly_p(VALUE str);
RBIMPL_ATTR_NONNULL(())
/**
* Looks for the passed string in the passed buffer.
*
* @param[in] x Buffer that potentially includes `y`.
* @param[in] m Number of bytes of `x`.
* @param[in] y Query string.
* @param[in] n Number of bytes of `y`.
* @param[in] enc Encoding of both `x` and `y`.
* @retval -1 Not found.
* @retval otherwise Found index in `x`.
* @note This API can match at a non-character-boundary.
*/
long rb_memsearch(const void *x, long m, const void *y, long n, rb_encoding *enc);
/** @cond INTERNAL_MACRO */
RBIMPL_ATTR_NONNULL(())
static inline VALUE
rbimpl_enc_str_new_cstr(const char *str, rb_encoding *enc)
{
long len = rbimpl_strlen(str);
return rb_enc_str_new_static(str, len, enc);
}
#define rb_enc_str_new(str, len, enc) \
((RBIMPL_CONSTANT_P(str) && \
RBIMPL_CONSTANT_P(len) ? \
rb_enc_str_new_static: \
rb_enc_str_new) ((str), (len), (enc)))
#define rb_enc_str_new_cstr(str, enc) \
((RBIMPL_CONSTANT_P(str) ? \
rbimpl_enc_str_new_cstr : \
rb_enc_str_new_cstr) ((str), (enc)))
/** @endcond */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_STRING_H */
include/ruby/internal/encoding/symbol.h 0000644 00000010650 15040330605 0014226 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_SYMBOL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_SYMBOL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate encodings of symbols.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Identical to rb_intern2(), except it additionally takes an encoding.
*
* @param[in] name The name of the id.
* @param[in] len Length of `name`.
* @param[in] enc `name`'s encoding.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given name.
* @note These days Ruby internally has two kinds of symbols
* (static/dynamic). Symbols created using this function would
* become static ones; i.e. would never be garbage collected. It
* is up to you to avoid memory leaks. Think twice before using
* it.
*/
ID rb_intern3(const char *name, long len, rb_encoding *enc);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_symname_p(), except it additionally takes an encoding.
*
* @param[in] str A C string to check.
* @param[in] enc `str`'s encoding.
* @retval 1 It is a valid symbol name.
* @retval 0 It is invalid as a symbol name.
*/
int rb_enc_symname_p(const char *str, rb_encoding *enc);
/**
* Identical to rb_enc_symname_p(), except it additionally takes the passed
* string's length. This is needed for strings containing NUL bytes, like in
* case of UTF-32.
*
* @param[in] name A C string to check.
* @param[in] len Number of bytes of `str`.
* @param[in] enc `str`'s encoding.
* @retval 1 It is a valid symbol name.
* @retval 0 It is invalid as a symbol name.
*/
int rb_enc_symname2_p(const char *name, long len, rb_encoding *enc);
/**
* Identical to rb_check_id(), except it takes a pointer to a memory region
* instead of Ruby's string.
*
* @param[in] ptr A pointer to a memory region.
* @param[in] len Number of bytes of `ptr`.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eEncodingError `ptr` contains non-ASCII according to `enc`.
* @retval 0 No such id ever existed in the history.
* @retval otherwise The id that represents the given name.
*/
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc);
/**
* Identical to rb_check_id_cstr(), except for the return type. It can also be
* seen as a routine identical to rb_check_symbol(), except it takes a pointer
* to a memory region instead of Ruby's string.
*
* @param[in] ptr A pointer to a memory region.
* @param[in] len Number of bytes of `ptr`.
* @param[in] enc Encoding of `ptr`.
* @exception rb_eEncodingError `ptr` contains non-ASCII according to `enc`.
* @retval RUBY_Qnil No such id ever existed in the history.
* @retval otherwise The id that represents the given name.
*/
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_SYMBOL_H */
include/ruby/internal/encoding/transcode.h 0000644 00000062175 15040330605 0014714 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_TRANSCODE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_TRANSCODE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief econv stuff
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/** return value of rb_econv_convert() */
typedef enum {
/**
* The conversion stopped when it found an invalid sequence.
*/
econv_invalid_byte_sequence,
/**
* The conversion stopped when it found a character in the input which
* cannot be representable in the output.
*/
econv_undefined_conversion,
/**
* The conversion stopped because there is no destination.
*/
econv_destination_buffer_full,
/**
* The conversion stopped because there is no input.
*/
econv_source_buffer_empty,
/**
* The conversion stopped after converting everything. This is arguably
* the expected normal end of conversion.
*/
econv_finished,
/**
* The conversion stopped after writing something to somewhere, before
* reading everything.
*/
econv_after_output,
/**
* The conversion stopped in middle of reading a character, possibly due to
* a partial read of a socket etc.
*/
econv_incomplete_input
} rb_econv_result_t;
/** An opaque struct that represents a lowest level of encoding conversion. */
typedef struct rb_econv_t rb_econv_t;
/**
* Converts the contents of the passed string from its encoding to the passed
* one.
*
* @param[in] str Target string.
* @param[in] to Destination encoding.
* @param[in] ecflags A set of enum
* ::ruby_econv_flag_type.
* @param[in] ecopts A keyword hash, like
* ::rb_io_t::rb_io_enc_t::ecopts.
* @exception rb_eArgError Not fully converted.
* @exception rb_eInvalidByteSequenceError `str` is malformed.
* @exception rb_eUndefinedConversionError `str` has a character not
* representable using `to`.
* @exception rb_eConversionNotFoundError There is no known conversion from
* `str`'s encoding to `to`.
* @return A string whose encoding is `to`, and whose contents is converted
* contents of `str`.
* @note Use rb_econv_prepare_options() to generate `ecopts`.
*/
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts);
/**
* Queries if there is more than one way to convert between the passed two
* encodings. Encoding conversion are has_and_belongs_to_many relationships.
* There could be no direct conversion defined for the passed pair. Ruby tries
* to find an indirect way to do so then. For instance ISO-8859-1 has no
* direct conversion to ISO-2022-JP. But there is ISO-8859-1 to UTF-8
* conversion; then there is UTF-8 to EUC-JP conversion; finally there also is
* EUC-JP to ISO-2022-JP conversion. So in short ISO-8859-1 can be converted
* to ISO-2022-JP using that path. This function returns true. Obviously not
* everything that can be represented using UTF-8 can also be represented using
* EUC-JP. Conversions in practice can fail depending on the actual input, and
* that renders exceptions in case of rb_str_encode().
*
* @param[in] from_encoding One encoding.
* @param[in] to_encoding Another encoding.
* @retval 0 No way to convert the two.
* @retval 1 At least one way to convert the two.
*
* @internal
*
* Practically @shyouhei knows no way for this function to return 0. It seems
* everything can eventually be converted to/from UTF-8, which connects
* everything.
*/
int rb_econv_has_convpath_p(const char* from_encoding, const char* to_encoding);
/**
* Identical to rb_econv_prepare_opts(), except it additionally takes the
* initial value of flags. The extra bits are bitwise-ORed to the return
* value.
*
* @param[in] opthash Keyword arguments.
* @param[out] ecopts Return buffer.
* @param[in] ecflags Default set of enum ::ruby_econv_flag_type.
* @exception rb_eArgError Unknown/Broken values passed.
* @return Calculated set of enum ::ruby_econv_flag_type.
* @post `ecopts` holds a hash object suitable for
* ::rb_io_t::rb_io_enc_t::ecopts.
*/
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags);
/**
* Splits a keyword arguments hash (that for instance `String#encode` took)
* into a set of enum ::ruby_econv_flag_type and a hash storing replacement
* characters etc.
*
* @param[in] opthash Keyword arguments.
* @param[out] ecopts Return buffer.
* @exception rb_eArgError Unknown/Broken values passed.
* @return Calculated set of enum ::ruby_econv_flag_type.
* @post `ecopts` holds a hash object suitable for
* ::rb_io_t::rb_io_enc_t::ecopts.
*/
int rb_econv_prepare_opts(VALUE opthash, VALUE *ecopts);
/**
* Creates a new instance of struct ::rb_econv_t.
*
* @param[in] source_encoding Name of an encoding.
* @param[in] destination_encoding Name of another encoding.
* @param[in] ecflags A set of enum ::ruby_econv_flag_type.
* @exception rb_eArgError No such encoding.
* @retval NULL Failed to create a struct ::rb_econv_t.
* @retval otherwise Allocated struct ::rb_econv_t.
* @warning Return value must be passed to rb_econv_close() exactly once.
*/
rb_econv_t *rb_econv_open(const char *source_encoding, const char *destination_encoding, int ecflags);
/**
* Identical to rb_econv_open(), except it additionally takes a hash of
* optional strings.
*
*
* @param[in] source_encoding Name of an encoding.
* @param[in] destination_encoding Name of another encoding.
* @param[in] ecflags A set of enum ::ruby_econv_flag_type.
* @param[in] ecopts Optional set of strings.
* @exception rb_eArgError No such encoding.
* @retval NULL Failed to create a struct ::rb_econv_t.
* @retval otherwise Allocated struct ::rb_econv_t.
* @warning Return value must be passed to rb_econv_close() exactly once.
*/
rb_econv_t *rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts);
/**
* Converts a string from an encoding to another.
*
* Possible flags are either ::RUBY_ECONV_PARTIAL_INPUT (means the source
* buffer is a part of much larger one), ::RUBY_ECONV_AFTER_OUTPUT (instructs
* the converter to stop after output before input), or both of them.
*
* @param[in,out] ec Conversion specification/state etc.
* @param[in] source_buffer_ptr Target string.
* @param[in] source_buffer_end End of target string.
* @param[out] destination_buffer_ptr Return buffer.
* @param[out] destination_buffer_end End of return buffer.
* @param[in] flags Flags (see above).
* @return The status of the conversion.
* @post `destination_buffer_ptr` holds conversion results.
*/
rb_econv_result_t rb_econv_convert(rb_econv_t *ec,
const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end,
unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end,
int flags);
/**
* Destructs a converter. Note that a converter can have a buffer, and can be
* non-empty. Calling this would lose your data then.
*
* @param[out] ec The converter to destroy.
* @post `ec` is no longer a valid pointer.
*/
void rb_econv_close(rb_econv_t *ec);
/**
* Assigns the replacement string. The string passed here would appear in
* converted string when it cannot represent its source counterpart. This can
* happen for instance you convert an emoji to ISO-8859-1.
*
* @param[out] ec Target converter.
* @param[in] str Replacement string.
* @param[in] len Number of bytes of `str`.
* @param[in] encname Name of encoding of `str`.
* @retval 0 Success.
* @retval -1 Failure (ENOMEM etc.).
* @post `ec`'s replacement string is set to `str`.
*/
int rb_econv_set_replacement(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname);
/**
* "Decorate"s a converter. There are special kind of converters that
* transforms the contents, like replacing CR into CRLF. You can add such
* decorators to a converter using this API. By using this function a
* decorator is prepended at the beginning of a conversion sequence: in case of
* CRLF conversion, newlines are converted before encodings are converted.
*
* @param[out] ec Target converter to decorate.
* @param[in] decorator_name Name of decorator to prepend.
* @retval 0 Success.
* @retval -1 Failure (no such decorator etc.).
* @post Decorator works before encoding conversion happens.
*
* @internal
*
* What is the possible value of the `decorator_name` is not public. You have
* to read through `transcode.c` carefully.
*/
int rb_econv_decorate_at_first(rb_econv_t *ec, const char *decorator_name);
/**
* Identical to rb_econv_decorate_at_first(), except it adds to the opposite
* direction. For instance CRLF conversion would run _after_ encodings are
* converted.
*
* @param[out] ec Target converter to decorate.
* @param[in] decorator_name Name of decorator to prepend.
* @retval 0 Success.
* @retval -1 Failure (no such decorator etc.).
* @post Decorator works after encoding conversion happens.
*/
int rb_econv_decorate_at_last(rb_econv_t *ec, const char *decorator_name);
/**
* Creates a `rb_eConverterNotFoundError` exception object (but does not
* raise).
*
* @param[in] senc Name of source encoding.
* @param[in] denc Name of destination encoding.
* @param[in] ecflags A set of enum ::ruby_econv_flag_type.
* @return An instance of `rb_eConverterNotFoundError`.
*/
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags);
/**
* Appends the passed string to the passed converter's output buffer. This can
* be handy when an encoding needs bytes out of thin air; for instance
* ISO-2022-JP has "shift function" which does not correspond to any
* characters.
*
* @param[out] ec Target converter.
* @param[in] str String to insert.
* @param[in] len Number of bytes of `str`.
* @param[in] str_encoding Encoding of `str`.
* @retval 0 Success.
* @retval -1 Failure (conversion error etc.).
* @note `str_encoding` can be anything, and `str` itself is converted
* when necessary.
*/
int rb_econv_insert_output(rb_econv_t *ec,
const unsigned char *str, size_t len, const char *str_encoding);
/**
* Queries an encoding name which best suits for rb_econv_insert_output()'s
* last parameter. Strings in this encoding need no conversion when inserted;
* can be both time/space efficient.
*
* @param[in] ec Target converter.
* @return Its encoding for insertion.
*/
const char *rb_econv_encoding_to_insert_output(rb_econv_t *ec);
/**
* This is a rb_econv_make_exception() + rb_exc_raise() combo.
*
* @param[in] ec (Possibly failed) conversion.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @note This function can return when no error.
*/
void rb_econv_check_error(rb_econv_t *ec);
/**
* This function makes sense right after rb_econv_convert() returns. As listed
* in ::rb_econv_result_t, rb_econv_convert() can bail out for various reasons.
* This function checks the passed converter's internal state and convert it to
* an appropriate exception object.
*
* @param[in] ec Target converter.
* @retval RUBY_Qnil The converter has no error.
* @retval otherwise Conversion error turned into an exception.
*/
VALUE rb_econv_make_exception(rb_econv_t *ec);
/**
* Queries if rb_econv_putback() makes sense, i.e. there are invalid byte
* sequences remain in the buffer.
*
* @param[in] ec Target converter.
* @return Number of bytes that can be pushed back.
*/
int rb_econv_putbackable(rb_econv_t *ec);
/**
* Puts back the bytes. In case of ::econv_invalid_byte_sequence, some of
* those invalid bytes are discarded and the others are buffered to be
* converted later. The latter bytes can be put back using this API.
*
* @param[out] ec Target converter (invalid byte sequence).
* @param[out] p Return buffer.
* @param[in] n Max number of bytes to put back.
* @post At most `n` bytes of what was put back is written to `p`.
*/
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n);
/**
* Queries the passed encoding's corresponding ASCII compatible encoding. "The
* corresponding ASCII compatible encoding" in this context is an ASCII
* compatible encoding which can represent exactly the same character sets as
* the given ASCII incompatible encoding. For instance that of UTF-16LE is
* UTF-8.
*
* @param[in] encname Name of an ASCII incompatible encoding.
* @retval NULL `encname` is already ASCII compatible.
* @retval otherwise The corresponding ASCII compatible encoding.
*/
const char *rb_econv_asciicompat_encoding(const char *encname);
/**
* Identical to rb_econv_convert(), except it takes Ruby's string instead of
* C's pointer.
*
* @param[in,out] ec Target converter.
* @param[in] src Source string.
* @param[in] flags Flags (see rb_econv_convert).
* @exception rb_eArgError Converted string is too long.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @return The conversion result.
*/
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags);
/**
* Identical to rb_econv_str_convert(), except it converts only a part of the
* passed string. Can be handy when you for instance want to do line-buffered
* conversion.
*
* @param[in,out] ec Target converter.
* @param[in] src Source string.
* @param[in] byteoff Number of bytes to seek.
* @param[in] bytesize Number of bytes to read.
* @param[in] flags Flags (see rb_econv_convert).
* @exception rb_eArgError Converted string is too long.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @return The conversion result.
*/
VALUE rb_econv_substr_convert(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, int flags);
/**
* Identical to rb_econv_str_convert(), except it appends the conversion result
* to the additionally passed string instead of creating a new string. It can
* also be seen as a routine identical to rb_econv_append(), except it takes a
* Ruby's string instead of C's pointer.
*
* @param[in,out] ec Target converter.
* @param[in] src Source string.
* @param[in] dst Return buffer.
* @param[in] flags Flags (see rb_econv_convert).
* @exception rb_eArgError Converted string is too long.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @return The conversion result.
*/
VALUE rb_econv_str_append(rb_econv_t *ec, VALUE src, VALUE dst, int flags);
/**
* Identical to rb_econv_str_append(), except it appends only a part of the
* passed string with conversion. It can also be seen as a routine identical
* to rb_econv_substr_convert(), except it appends the conversion result to the
* additionally passed string instead of creating a new string.
*
* @param[in,out] ec Target converter.
* @param[in] src Source string.
* @param[in] byteoff Number of bytes to seek.
* @param[in] bytesize Number of bytes to read.
* @param[in] dst Return buffer.
* @param[in] flags Flags (see rb_econv_convert).
* @exception rb_eArgError Converted string is too long.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @return The conversion result.
*/
VALUE rb_econv_substr_append(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, VALUE dst, int flags);
/**
* Converts the passed C's pointer according to the passed converter, then
* append the conversion result to the passed Ruby's string. This way buffer
* overflow is properly avoided to resize the destination properly.
*
* @param[in,out] ec Target converter.
* @param[in] bytesrc Target string.
* @param[in] bytesize Number of bytes of `bytesrc`.
* @param[in] dst Return buffer.
* @param[in] flags Flags (see rb_econv_convert).
* @exception rb_eArgError Converted string is too long.
* @exception rb_eInvalidByteSequenceError Invalid byte sequence.
* @exception rb_eUndefinedConversionError Conversion undefined.
* @return The conversion result.
*/
VALUE rb_econv_append(rb_econv_t *ec, const char *bytesrc, long bytesize, VALUE dst, int flags);
/**
* This badly named function does not set the destination encoding to binary,
* but instead just nullifies newline conversion decorators if any. Other
* ordinal character conversions still happen after this; something non-binary
* would still be generated.
*
* @param[out] ec Target converter to modify.
* @post Any newline conversions, if any, would be killed.
*/
void rb_econv_binmode(rb_econv_t *ec);
/**
* This enum is kind of omnibus. Gathers various constants.
*/
enum ruby_econv_flag_type {
/**
* @name Flags for rb_econv_open()
*
* @{
*/
/** Mask for error handling related bits. */
RUBY_ECONV_ERROR_HANDLER_MASK = 0x000000ff,
/** Special handling of invalid sequences are there. */
RUBY_ECONV_INVALID_MASK = 0x0000000f,
/** Invalid sequences shall be replaced. */
RUBY_ECONV_INVALID_REPLACE = 0x00000002,
/** Special handling of undefined conversion are there. */
RUBY_ECONV_UNDEF_MASK = 0x000000f0,
/** Undefined characters shall be replaced. */
RUBY_ECONV_UNDEF_REPLACE = 0x00000020,
/** Undefined characters shall be escaped. */
RUBY_ECONV_UNDEF_HEX_CHARREF = 0x00000030,
/** Decorators are there. */
RUBY_ECONV_DECORATOR_MASK = 0x0001ff00,
/** Newline converters are there. */
RUBY_ECONV_NEWLINE_DECORATOR_MASK = 0x00007f00,
/** (Unclear; seems unused). */
RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK = 0x00000f00,
/** (Unclear; seems unused). */
RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK = 0x00007000,
/** Universal newline mode. */
RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR = 0x00000100,
/** CR to CRLF conversion shall happen. */
RUBY_ECONV_CRLF_NEWLINE_DECORATOR = 0x00001000,
/** CRLF to CR conversion shall happen. */
RUBY_ECONV_CR_NEWLINE_DECORATOR = 0x00002000,
/** CRLF to LF conversion shall happen. */
RUBY_ECONV_LF_NEWLINE_DECORATOR = 0x00004000,
/** Texts shall be XML-escaped. */
RUBY_ECONV_XML_TEXT_DECORATOR = 0x00008000,
/** Texts shall be AttrValue escaped */
RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR = 0x00010000,
/** (Unclear; seems unused). */
RUBY_ECONV_STATEFUL_DECORATOR_MASK = 0x00f00000,
/** Texts shall be AttrValue escaped. */
RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR = 0x00100000,
/** Newline decorator's default. */
RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR =
#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
RUBY_ECONV_CRLF_NEWLINE_DECORATOR,
#else
0,
#endif
#define ECONV_ERROR_HANDLER_MASK RUBY_ECONV_ERROR_HANDLER_MASK /**< @old{RUBY_ECONV_ERROR_HANDLER_MASK} */
#define ECONV_INVALID_MASK RUBY_ECONV_INVALID_MASK /**< @old{RUBY_ECONV_INVALID_MASK} */
#define ECONV_INVALID_REPLACE RUBY_ECONV_INVALID_REPLACE /**< @old{RUBY_ECONV_INVALID_REPLACE} */
#define ECONV_UNDEF_MASK RUBY_ECONV_UNDEF_MASK /**< @old{RUBY_ECONV_UNDEF_MASK} */
#define ECONV_UNDEF_REPLACE RUBY_ECONV_UNDEF_REPLACE /**< @old{RUBY_ECONV_UNDEF_REPLACE} */
#define ECONV_UNDEF_HEX_CHARREF RUBY_ECONV_UNDEF_HEX_CHARREF /**< @old{RUBY_ECONV_UNDEF_HEX_CHARREF} */
#define ECONV_DECORATOR_MASK RUBY_ECONV_DECORATOR_MASK /**< @old{RUBY_ECONV_DECORATOR_MASK} */
#define ECONV_NEWLINE_DECORATOR_MASK RUBY_ECONV_NEWLINE_DECORATOR_MASK /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_MASK} */
#define ECONV_NEWLINE_DECORATOR_READ_MASK RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK} */
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK} */
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR} */
#define ECONV_CRLF_NEWLINE_DECORATOR RUBY_ECONV_CRLF_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_CRLF_NEWLINE_DECORATOR} */
#define ECONV_CR_NEWLINE_DECORATOR RUBY_ECONV_CR_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_CR_NEWLINE_DECORATOR} */
#define ECONV_LF_NEWLINE_DECORATOR RUBY_ECONV_LF_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_LF_NEWLINE_DECORATOR} */
#define ECONV_XML_TEXT_DECORATOR RUBY_ECONV_XML_TEXT_DECORATOR /**< @old{RUBY_ECONV_XML_TEXT_DECORATOR} */
#define ECONV_XML_ATTR_CONTENT_DECORATOR RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR /**< @old{RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR} */
#define ECONV_STATEFUL_DECORATOR_MASK RUBY_ECONV_STATEFUL_DECORATOR_MASK /**< @old{RUBY_ECONV_STATEFUL_DECORATOR_MASK} */
#define ECONV_XML_ATTR_QUOTE_DECORATOR RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR /**< @old{RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR} */
#define ECONV_DEFAULT_NEWLINE_DECORATOR RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR} */
/** @} */
/**
* @name Flags for rb_econv_convert()
*
* @{
*/
/** Indicates the input is a part of much larger one. */
RUBY_ECONV_PARTIAL_INPUT = 0x00020000,
/** Instructs the converter to stop after output. */
RUBY_ECONV_AFTER_OUTPUT = 0x00040000,
#define ECONV_PARTIAL_INPUT RUBY_ECONV_PARTIAL_INPUT /**< @old{RUBY_ECONV_PARTIAL_INPUT} */
#define ECONV_AFTER_OUTPUT RUBY_ECONV_AFTER_OUTPUT /**< @old{RUBY_ECONV_AFTER_OUTPUT} */
RUBY_ECONV_FLAGS_PLACEHOLDER /**< Placeholder (not used) */
};
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_TRANSCODE_H */
include/ruby/internal/encoding/sprintf.h 0000644 00000006600 15040330605 0014406 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_SPRINTF_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_SPRINTF_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate encodings of symbols.
*/
#include "ruby/internal/config.h"
#include <stdarg.h>
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
* Identical to rb_sprintf(), except it additionally takes an encoding. The
* passed encoding rules both the incoming format specifier and the resulting
* string.
*
* @param[in] enc Encoding of `fmt`.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ... Variadic number of contents to format.
* @return A rendered new instance of ::rb_cString, of `enc` encoding.
*/
VALUE rb_enc_sprintf(rb_encoding *enc, const char *fmt, ...);
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
/**
* Identical to rb_enc_sprintf(), except it takes a `va_list` instead of
* variadic arguments. It can also be seen as a routine identical to
* rb_vsprintf(), except it additionally takes an encoding.
*
* @param[in] enc Encoding of `fmt`.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ap Contents to format.
* @return A rendered new instance of ::rb_cString, of `enc` encoding.
*/
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap);
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
* Identical to rb_raise(), except it additionally takes an encoding.
*
* @param[in] enc Encoding of the generating exception.
* @param[in] exc A subclass of ::rb_eException.
* @param[in] fmt Format specifier string compatible with rb_sprintf().
* @param[in] ... Contents of the message.
* @exception exc The specified exception.
* @note It never returns.
*/
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_SPRINTF_H */
include/ruby/internal/encoding/coderange.h 0000644 00000017616 15040330605 0014661 0 ustar 00 #ifndef RUBY_INTERNAL_ENCODING_CODERANGE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_CODERANGE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines for code ranges.
*/
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/** What rb_enc_str_coderange() returns. */
enum ruby_coderange_type {
/** The object's coderange is unclear yet. */
RUBY_ENC_CODERANGE_UNKNOWN = 0,
/** The object holds 0 to 127 inclusive and nothing else. */
RUBY_ENC_CODERANGE_7BIT = ((int)RUBY_FL_USER8),
/** The object's encoding and contents are consistent each other */
RUBY_ENC_CODERANGE_VALID = ((int)RUBY_FL_USER9),
/** The object holds invalid/malformed/broken character(s). */
RUBY_ENC_CODERANGE_BROKEN = ((int)(RUBY_FL_USER8|RUBY_FL_USER9)),
/** Where the coderange resides. */
RUBY_ENC_CODERANGE_MASK = (RUBY_ENC_CODERANGE_7BIT|
RUBY_ENC_CODERANGE_VALID|
RUBY_ENC_CODERANGE_BROKEN)
};
RBIMPL_ATTR_CONST()
/**
* @private
*
* This is an implementation detail of #RB_ENC_CODERANGE_CLEAN_P. People don't
* use it directly.
*
* @param[in] cr An enum ::ruby_coderange_type.
* @retval 1 It is.
* @retval 0 It isn't.
*/
static inline int
rb_enc_coderange_clean_p(int cr)
{
return (cr ^ (cr >> 1)) & RUBY_ENC_CODERANGE_7BIT;
}
RBIMPL_ATTR_CONST()
/**
* Queries if a code range is "clean". "Clean" in this context means it is
* known and valid.
*
* @param[in] cr An enum ::ruby_coderange_type.
* @retval 1 It is.
* @retval 0 It isn't.
*/
static inline bool
RB_ENC_CODERANGE_CLEAN_P(enum ruby_coderange_type cr)
{
return rb_enc_coderange_clean_p(cr);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* Queries the (inline) code range of the passed object. The object must be
* capable of having inline encoding. Using this macro needs deep
* understanding of bit level object binary layout.
*
* @param[in] obj Target object.
* @return An enum ::ruby_coderange_type.
*/
static inline enum ruby_coderange_type
RB_ENC_CODERANGE(VALUE obj)
{
VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENC_CODERANGE_MASK);
return RBIMPL_CAST((enum ruby_coderange_type)ret);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* Queries the (inline) code range of the passed object is
* ::RUBY_ENC_CODERANGE_7BIT. The object must be capable of having inline
* encoding. Using this macro needs deep understanding of bit level object
* binary layout.
*
* @param[in] obj Target object.
* @retval 1 It is ascii only.
* @retval 0 Otherwise (including cases when the range is not known).
*/
static inline bool
RB_ENC_CODERANGE_ASCIIONLY(VALUE obj)
{
return RB_ENC_CODERANGE(obj) == RUBY_ENC_CODERANGE_7BIT;
}
/**
* Destructively modifies the passed object so that its (inline) code range is
* the passed one. The object must be capable of having inline encoding.
* Using this macro needs deep understanding of bit level object binary layout.
*
* @param[out] obj Target object.
* @param[out] cr An enum ::ruby_coderange_type.
* @post `obj`'s code range is `cr`.
*/
static inline void
RB_ENC_CODERANGE_SET(VALUE obj, enum ruby_coderange_type cr)
{
RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
RB_FL_SET_RAW(obj, cr);
}
/**
* Destructively clears the passed object's (inline) code range. The object
* must be capable of having inline encoding. Using this macro needs deep
* understanding of bit level object binary layout.
*
* @param[out] obj Target object.
* @post `obj`'s code range is ::RUBY_ENC_CODERANGE_UNKNOWN.
*/
static inline void
RB_ENC_CODERANGE_CLEAR(VALUE obj)
{
RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
}
RBIMPL_ATTR_CONST()
/* assumed ASCII compatibility */
/**
* "Mix" two code ranges into one. This is handy for instance when you
* concatenate two strings into one. Consider one of then is valid but the
* other isn't. The result must be invalid. This macro computes that kind of
* mixture.
*
* @param[in] a An enum ::ruby_coderange_type.
* @param[in] b Another enum ::ruby_coderange_type.
* @return The `a` "and" `b`.
*/
static inline enum ruby_coderange_type
RB_ENC_CODERANGE_AND(enum ruby_coderange_type a, enum ruby_coderange_type b)
{
if (a == RUBY_ENC_CODERANGE_7BIT) {
return b;
}
else if (a != RUBY_ENC_CODERANGE_VALID) {
return RUBY_ENC_CODERANGE_UNKNOWN;
}
else if (b == RUBY_ENC_CODERANGE_7BIT) {
return RUBY_ENC_CODERANGE_VALID;
}
else {
return b;
}
}
#define ENC_CODERANGE_MASK RUBY_ENC_CODERANGE_MASK /**< @old{RUBY_ENC_CODERANGE_MASK} */
#define ENC_CODERANGE_UNKNOWN RUBY_ENC_CODERANGE_UNKNOWN /**< @old{RUBY_ENC_CODERANGE_UNKNOWN} */
#define ENC_CODERANGE_7BIT RUBY_ENC_CODERANGE_7BIT /**< @old{RUBY_ENC_CODERANGE_7BIT} */
#define ENC_CODERANGE_VALID RUBY_ENC_CODERANGE_VALID /**< @old{RUBY_ENC_CODERANGE_VALID} */
#define ENC_CODERANGE_BROKEN RUBY_ENC_CODERANGE_BROKEN /**< @old{RUBY_ENC_CODERANGE_BROKEN} */
#define ENC_CODERANGE_CLEAN_P(cr) RB_ENC_CODERANGE_CLEAN_P(cr) /**< @old{RB_ENC_CODERANGE_CLEAN_P} */
#define ENC_CODERANGE(obj) RB_ENC_CODERANGE(obj) /**< @old{RB_ENC_CODERANGE} */
#define ENC_CODERANGE_ASCIIONLY(obj) RB_ENC_CODERANGE_ASCIIONLY(obj) /**< @old{RB_ENC_CODERANGE_ASCIIONLY} */
#define ENC_CODERANGE_SET(obj,cr) RB_ENC_CODERANGE_SET(obj,cr) /**< @old{RB_ENC_CODERANGE_SET} */
#define ENC_CODERANGE_CLEAR(obj) RB_ENC_CODERANGE_CLEAR(obj) /**< @old{RB_ENC_CODERANGE_CLEAR} */
#define ENC_CODERANGE_AND(a, b) RB_ENC_CODERANGE_AND(a, b) /**< @old{RB_ENC_CODERANGE_AND} */
#define ENCODING_CODERANGE_SET(obj, encindex, cr) RB_ENCODING_CODERANGE_SET(obj, encindex, cr) /**< @old{RB_ENCODING_CODERANGE_SET} */
/** @cond INTERNAL_MACRO */
#define RB_ENC_CODERANGE RB_ENC_CODERANGE
#define RB_ENC_CODERANGE_AND RB_ENC_CODERANGE_AND
#define RB_ENC_CODERANGE_ASCIIONLY RB_ENC_CODERANGE_ASCIIONLY
#define RB_ENC_CODERANGE_CLEAN_P RB_ENC_CODERANGE_CLEAN_P
#define RB_ENC_CODERANGE_CLEAR RB_ENC_CODERANGE_CLEAR
#define RB_ENC_CODERANGE_SET RB_ENC_CODERANGE_SET
/** @endcond */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_INTERNAL_ENCODING_CODERANGE_H */
include/ruby/internal/has/cpp_attribute.h 0000644 00000010701 15040330605 0014550 0 ustar 00 #ifndef RBIMPL_HAS_CPP_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_CPP_ATTRIBUTE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_CPP_ATTRIBUTE.
*/
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/compiler_since.h"
/** @cond INTERNAL_MACRO */
#if RBIMPL_COMPILER_IS(SunPro)
# /* Oracle Developer Studio 12.5's C++ preprocessor is reportedly broken. We
# * could simulate __has_cpp_attribute like below, but don't know the exact
# * list of which version supported which attribute. Just kill everything for
# * now. If you can please :FIXME: */
# /* https://unicode-org.atlassian.net/browse/ICU-12893 */
# /* https://github.com/boostorg/config/pull/95 */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0
#elif defined(__has_cpp_attribute)
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) __has_cpp_attribute(_)
#elif RBIMPL_COMPILER_IS(MSVC)
# /* MSVC has never updated its __cplusplus since forever (unless specified
# * explicitly by a compiler flag). They also lack __has_cpp_attribute until
# * 2019. However, they do have attributes since 2015 or so. */
# /* https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_carries_dependency 200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_fallthrough 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_maybe_unused 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_nodiscard 201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)
#elif RBIMPL_COMPILER_BEFORE(Clang, 3, 6, 0)
# /* Clang 3.6.0 introduced __has_cpp_attribute. Prior to that following
# * attributes were already there. */
# /* https://clang.llvm.org/cxx_status.html */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(Clang, 3, 3, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(Clang, 3, 4, 0)
#elif RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
# /* GCC 5+ have __has_cpp_attribute, while 4.x had following attributes. */
# /* https://gcc.gnu.org/projects/cxx-status.html */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn 200809 * RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated 201309 * RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
#else
# /* :FIXME:
# * Candidate compilers to list here:
# * - icpc: They have __INTEL_CXX11_MODE__.
# */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0
#endif
/** @endcond */
/** Wraps (or simulates) `__has_cpp_attribute`. */
#if ! defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_CPP_ATTRIBUTE(_) 0
#else
# /* GCC needs workarounds. See https://gcc.godbolt.org/z/jdz3pa */
# define RBIMPL_HAS_CPP_ATTRIBUTE(_) \
((RBIMPL_HAS_CPP_ATTRIBUTE0(_) <= __cplusplus) ? RBIMPL_HAS_CPP_ATTRIBUTE0(_) : 0)
#endif
#endif /* RBIMPL_HAS_CPP_ATTRIBUTE_H */
include/ruby/internal/has/extension.h 0000644 00000003242 15040330605 0013721 0 ustar 00 #ifndef RBIMPL_HAS_EXTENSION_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_EXTENSION_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_EXTENSION.
*/
#include "ruby/internal/has/feature.h"
/** Wraps (or simulates) `__has_extension`. */
#if defined(__has_extension)
# define RBIMPL_HAS_EXTENSION(_) __has_extension(_)
#else
# /* Pre-3.0 clang had __has_feature but not __has_extension. */
# define RBIMPL_HAS_EXTENSION(_) RBIMPL_HAS_FEATURE(_)
#endif
#endif /* RBIMPL_HAS_EXTENSION_H */
include/ruby/internal/has/feature.h 0000644 00000003026 15040330605 0013340 0 ustar 00 #ifndef RBIMPL_HAS_FEATURE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_FEATURE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_FEATURE.
*/
/** Wraps (or simulates) `__has_feature`. */
#if defined(__has_feature)
# define RBIMPL_HAS_FEATURE(_) __has_feature(_)
#else
# define RBIMPL_HAS_FEATURE(_) 0
#endif
#endif /* RBIMPL_HAS_FEATURE_H */
include/ruby/internal/has/builtin.h 0000644 00000016162 15040330605 0013360 0 ustar 00 #ifndef RBIMPL_HAS_BUILTIN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_BUILTIN_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_BUILTIN.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_since.h"
#if defined(__has_builtin)
# if RBIMPL_COMPILER_IS(Intel)
# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is
# * reportedly broken. We have to skip them. However the situation can
# * change. They might improve someday. We need to revisit here later. */
# elif RBIMPL_COMPILER_IS(GCC) && ! __has_builtin(__builtin_alloca)
# /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of
# * __has_builtin. Cygwin copied that content to be a victim of the
# * broken-ness. We don't take them into account. */
# else
# define RBIMPL_HAVE___HAS_BUILTIN 1
# endif
#endif
/** Wraps (or simulates) `__has_builtin`. */
#if defined(RBIMPL_HAVE___HAS_BUILTIN)
# define RBIMPL_HAS_BUILTIN(_) __has_builtin(_)
#elif RBIMPL_COMPILER_IS(GCC)
# /* :FIXME: Historically GCC has had tons of builtins, but it implemented
# * __has_builtin only since GCC 10. This section can be made more
# * granular. */
# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 */
# define RBIMPL_HAS_BUILTIN(_) (RBIMPL_HAS_BUILTIN_ ## _)
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_alloca RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align RBIMPL_COMPILER_SINCE(GCC, 6, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_assume 0
# /* See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 for bswap16. */
# define RBIMPL_HAS_BUILTIN___builtin_bswap16 RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
#ifndef __OpenBSD__
# define RBIMPL_HAS_BUILTIN___builtin_bswap32 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_bswap64 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#endif
# define RBIMPL_HAS_BUILTIN___builtin_clz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_constant_p RBIMPL_COMPILER_SINCE(GCC, 2,95, 3)
# define RBIMPL_HAS_BUILTIN___builtin_ctz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_ctzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_ctzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_expect RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcount RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcountl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcountll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft32 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft64 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright32 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright64 0
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_unreachable RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
# /* Note that "0, 0, 0" might be inaccurate. */
#else
# /* Take config.h definition when available */
# define RBIMPL_HAS_BUILTIN(_) ((RBIMPL_HAS_BUILTIN_ ## _)+0)
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
# define RBIMPL_HAS_BUILTIN___builtin_alloca 0
# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
# define RBIMPL_HAS_BUILTIN___builtin_assume 0
# define RBIMPL_HAS_BUILTIN___builtin_assume_aligned HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
# define RBIMPL_HAS_BUILTIN___builtin_bswap16 HAVE_BUILTIN___BUILTIN_BSWAP16
# define RBIMPL_HAS_BUILTIN___builtin_bswap32 HAVE_BUILTIN___BUILTIN_BSWAP32
# define RBIMPL_HAS_BUILTIN___builtin_bswap64 HAVE_BUILTIN___BUILTIN_BSWAP64
# define RBIMPL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ
# define RBIMPL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL
# define RBIMPL_HAS_BUILTIN___builtin_clzll HAVE_BUILTIN___BUILTIN_CLZLL
# define RBIMPL_HAS_BUILTIN___builtin_constant_p HAVE_BUILTIN___BUILTIN_CONSTANT_P
# define RBIMPL_HAS_BUILTIN___builtin_ctz HAVE_BUILTIN___BUILTIN_CTZ
# define RBIMPL_HAS_BUILTIN___builtin_ctzl 0
# define RBIMPL_HAS_BUILTIN___builtin_ctzll HAVE_BUILTIN___BUILTIN_CTZLL
# define RBIMPL_HAS_BUILTIN___builtin_expect HAVE_BUILTIN___BUILTIN_EXPECT
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
# define RBIMPL_HAS_BUILTIN___builtin_popcount HAVE_BUILTIN___BUILTIN_POPCOUNT
# define RBIMPL_HAS_BUILTIN___builtin_popcountl 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft32 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft64 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright32 0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright64 0
# define RBIMPL_HAS_BUILTIN___builtin_popcountll HAVE_BUILTIN___BUILTIN_POPCOUNTLL
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
# if defined(HAVE___BUILTIN_UNREACHABLE)
# define RBIMPL_HAS_BUILTIN___builtin_unreachable 1
# else
# define RBIMPL_HAS_BUILTIN___builtin_unreachable 0
# endif
#endif
#endif /* RBIMPL_HAS_BUILTIN_H */
include/ruby/internal/has/declspec_attribute.h 0000644 00000005371 15040330606 0015560 0 ustar 00 #ifndef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_DECLSPEC_ATTRIBUTE.
*/
#include "ruby/internal/compiler_since.h"
/** Wraps (or simulates) `__has_declspec_attribute`. */
#if defined(__has_declspec_attribute)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) __has_declspec_attribute(_)
#else
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) (RBIMPL_HAS_DECLSPEC_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_align RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_deprecated RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllexport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllimport RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_empty_bases RBIMPL_COMPILER_SINCE(MSVC,19, 0, 23918)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noalias RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(MSVC,11, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_restrict RBIMPL_COMPILER_SINCE(MSVC,14, 0, 0)
# /* Note that "8, 0, 0" might be inaccurate. */
# if ! defined(__cplusplus)
# /* Clang has this in both C/C++, but MSVC has this in C++ only.*/
# undef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow
# endif
#endif
#endif /* RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H */
include/ruby/internal/has/c_attribute.h 0000644 00000003437 15040330606 0014221 0 ustar 00 #ifndef RBIMPL_HAS_C_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_C_ATTRIBUTE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_C_ATTRIBUTE.
*/
/** Wraps (or simulates) `__has_c_attribute`. */
#if defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
#elif defined(__has_c_attribute)
# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)
#else
# /* As of writing everything that lacks __has_c_attribute also completely
# * lacks C2x attributes as well. Might change in future? */
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
#endif
#endif /* RBIMPL_HAS_C_ATTRIBUTE_H */
include/ruby/internal/has/attribute.h 0000644 00000020510 15040330606 0013706 0 ustar 00 #ifndef RBIMPL_HAS_ATTRIBUTE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_ATTRIBUTE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_ATTRIBUTE.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_since.h"
#if defined(__has_attribute)
# if __has_attribute(pure) || RBIMPL_COMPILER_IS(GCC)
# /* FreeBSD's <sys/cdefs.h> defines its own *broken* version of
# * __has_attribute. Cygwin copied that content to be a victim of the
# * broken-ness. We don't take them into account. */
# define RBIMPL_HAVE___HAS_ATTRIBUTE 1
# endif
#endif
/** Wraps (or simulates) `__has_attribute`. */
#if defined(RBIMPL_HAVE___HAS_ATTRIBUTE)
# define RBIMPL_HAS_ATTRIBUTE(_) __has_attribute(_)
#elif RBIMPL_COMPILER_IS(GCC)
# /* GCC <= 4 lack __has_attribute predefined macro, while have attributes
# * themselves. We can simulate the macro like the following: */
# define RBIMPL_HAS_ATTRIBUTE(_) (RBIMPL_HAS_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_ATTRIBUTE_aligned RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_alloc_size RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_artificial RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_always_inline RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_cdecl RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_cold RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_const RBIMPL_COMPILER_SINCE(GCC, 2, 6, 0)
# define RBIMPL_HAS_ATTRIBUTE_deprecated RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_dllexport RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_dllimport RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_error RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_format RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_hot RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_leaf RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# define RBIMPL_HAS_ATTRIBUTE_malloc RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_undefined RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_nonnull RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(GCC, 2, 5, 0)
# define RBIMPL_HAS_ATTRIBUTE_nothrow RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_pure RBIMPL_COMPILER_SINCE(GCC, 2,96, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_nonnull RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_twice RBIMPL_COMPILER_SINCE(GCC, 4, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_stdcall RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_unused RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_visibility RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_warn_unused_result RBIMPL_COMPILER_SINCE(GCC, 3, 4, 0)
# define RBIMPL_HAS_ATTRIBUTE_warning RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_weak RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# /* Note that "0, 0, 0" might be inaccurate. */
#elif RBIMPL_COMPILER_IS(SunPro)
# /* Oracle Solaris Studio 12.4 (cc version 5.11) introduced __has_attribute.
# * Before that, following attributes were available. */
# /* See https://docs.oracle.com/cd/F24633_01/index.html */
# define RBIMPL_HAS_ATTRIBUTE(_) (RBIMPL_HAS_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_ATTRIBUTE_alias RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_aligned RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_always_inline RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_const RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_constructor RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_destructor RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_malloc RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noinline RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noreturn RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_packed RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_pure RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_twice RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_vector_size RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_visibility RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_weak RBIMPL_COMPILER_SINCE(SunPro, 5, 9, 0)
#elif defined (_MSC_VER)
# define RBIMPL_HAS_ATTRIBUTE(_) 0
# /* Fallback below doesn't work: see win32/Makefile.sub */
#else
# /* Take config.h definition when available. */
# define RBIMPL_HAS_ATTRIBUTE(_) ((RBIMPL_HAS_ATTRIBUTE_ ## _)+0)
# ifdef ALWAYS_INLINE
# define RBIMPL_HAS_ATTRIBUTE_always_inline 1
# endif
# ifdef FUNC_CDECL
# define RBIMPL_HAS_ATTRIBUTE_cdecl 1
# endif
# ifdef CONSTFUNC
# define RBIMPL_HAS_ATTRIBUTE_const 1
# endif
# ifdef DEPRECATED
# define RBIMPL_HAS_ATTRIBUTE_deprecated 1
# endif
# ifdef ERRORFUNC
# define RBIMPL_HAS_ATTRIBUTE_error 1
# endif
# ifdef FUNC_FASTCALL
# define RBIMPL_HAS_ATTRIBUTE_fastcall 1
# endif
# ifdef PUREFUNC
# define RBIMPL_HAS_ATTRIBUTE_pure 1
# endif
# ifdef NO_ADDRESS_SAFETY_ANALYSIS
# define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis 1
# endif
# ifdef NO_SANITIZE
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize 1
# endif
# ifdef NO_SANITIZE_ADDRESS
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address 1
# endif
# ifdef NOINLINE
# define RBIMPL_HAS_ATTRIBUTE_noinline 1
# endif
# ifdef RBIMPL_FUNC_NONNULL
# define RBIMPL_HAS_ATTRIBUTE_nonnull 1
# endif
# ifdef NORETURN
# define RBIMPL_HAS_ATTRIBUTE_noreturn 1
# endif
# ifdef FUNC_OPTIMIZED
# define RBIMPL_HAS_ATTRIBUTE_optimize 1
# endif
# ifdef FUNC_STDCALL
# define RBIMPL_HAS_ATTRIBUTE_stdcall 1
# endif
# ifdef MAYBE_UNUSED
# define RBIMPL_HAS_ATTRIBUTE_unused 1
# endif
# ifdef WARN_UNUSED_RESULT
# define RBIMPL_HAS_ATTRIBUTE_warn_unused_result 1
# endif
# ifdef WARNINGFUNC
# define RBIMPL_HAS_ATTRIBUTE_warning 1
# endif
# ifdef WEAK
# define RBIMPL_HAS_ATTRIBUTE_weak 1
# endif
#endif
#endif /* RBIMPL_HAS_ATTRIBUTE_H */
include/ruby/internal/has/warning.h 0000644 00000003026 15040330606 0013353 0 ustar 00 #ifndef RBIMPL_HAS_WARNING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_WARNING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_HAS_WARNING.
*/
/** Wraps (or simulates) `__has_warning`. */
#if defined(__has_warning)
# define RBIMPL_HAS_WARNING(_) __has_warning(_)
#else
# define RBIMPL_HAS_WARNING(_) 0
#endif
#endif /* RBIMPL_HAS_WARNING_H */
include/ruby/internal/config.h 0000644 00000011512 15040330606 0012377 0 ustar 00 #ifndef RBIMPL_CONFIG_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CONFIG_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Thin wrapper to ruby/config.h
*/
#include "ruby/config.h"
#ifdef RUBY_EXTCONF_H
# include RUBY_EXTCONF_H
#endif
#include "ruby/internal/compiler_since.h"
#undef HAVE_PROTOTYPES
#define HAVE_PROTOTYPES 1
#undef HAVE_STDARG_PROTOTYPES
#define HAVE_STDARG_PROTOTYPES 1
#undef TOKEN_PASTE
#define TOKEN_PASTE(x,y) x##y
#if defined(__cplusplus)
#/* __builtin_choose_expr and __builtin_types_compatible aren't available
# * on C++. See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
# undef HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P
/* HAVE_VA_ARGS_MACRO is for C. C++ situations might be different. */
# undef HAVE_VA_ARGS_MACRO
# if __cplusplus >= 201103L
# define HAVE_VA_ARGS_MACRO
# elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
# define HAVE_VA_ARGS_MACRO
# elif defined(__INTEL_CXX11_MODE__)
# define HAVE_VA_ARGS_MACRO
# elif RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
# define HAVE_VA_ARGS_MACRO
# else
# /* NG, not known. */
# endif
#endif
#if RBIMPL_COMPILER_BEFORE(GCC, 4, 9, 0)
# /* See https://bugs.ruby-lang.org/issues/14221 */
# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
#endif
#if RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
# /* GCC 4.9.2 reportedly has this feature and is broken. The function is not
# * officially documented below. Seems we should not use it.
# * https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Other-Builtins.html */
# undef HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
#endif
#if defined(__SUNPRO_CC)
# /* Oracle Developer Studio 12.5: GCC compatibility guide says it supports
# * statement expressions. But to our knowledge they support the extension
# * only for C and not for C++. Prove me wrong. Am happy to support them if
# * there is a way. */
# undef HAVE_STMT_AND_DECL_IN_EXPR
#endif
#ifndef STRINGIZE0
# define STRINGIZE(expr) STRINGIZE0(expr)
# define STRINGIZE0(expr) #expr
#endif
#ifdef AC_APPLE_UNIVERSAL_BUILD
# undef WORDS_BIGENDIAN
# ifdef __BIG_ENDIAN__
# define WORDS_BIGENDIAN
# endif
#endif
#ifndef DLEXT_MAXLEN
# define DLEXT_MAXLEN 4
#endif
#ifndef RUBY_PLATFORM
# define RUBY_PLATFORM "unknown-unknown"
#endif
#ifdef UNALIGNED_WORD_ACCESS
# /* Take that. */
#elif defined(__i386)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__i386__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(_M_IX86)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__x86_64)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__x86_64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(_M_AMD64)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__powerpc64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__POWERPC__) // __POWERPC__ is defined for ppc and ppc64 on Darwin
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__aarch64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1
#else
# define UNALIGNED_WORD_ACCESS 0
#endif
/* Detection of __VA_OPT__ */
#if ! defined(HAVE_VA_ARGS_MACRO)
# undef HAVE___VA_OPT__
#elif defined(__cplusplus)
# if __cplusplus > 201703L
# define HAVE___VA_OPT__
# else
# undef HAVE___VA_OPT__
# endif
#else
# /* Idea taken from: https://stackoverflow.com/a/48045656 */
# define RBIMPL_TEST3(q, w, e, ...) e
# define RBIMPL_TEST2(...) RBIMPL_TEST3(__VA_OPT__(,),1,0,0)
# define RBIMPL_TEST1() RBIMPL_TEST2("ruby")
# if RBIMPL_TEST1()
# define HAVE___VA_OPT__
# else
# undef HAVE___VA_OPT__
# endif
# undef RBIMPL_TEST1
# undef RBIMPL_TEST2
# undef RBIMPL_TEST3
#endif /* HAVE_VA_ARGS_MACRO */
#ifndef USE_RVARGC
# define USE_RVARGC 1
#endif
#endif /* RBIMPL_CONFIG_H */
include/ruby/internal/core/rdata.h 0000644 00000033571 15040330606 0013166 0 ustar 00 #ifndef RBIMPL_RDATA_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RDATA_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RData.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/warning.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/defines.h"
/** @cond INTERNAL_MACRO */
#ifdef RUBY_UNTYPED_DATA_WARNING
# /* Take that. */
#elif defined(RUBY_EXPORT)
# define RUBY_UNTYPED_DATA_WARNING 1
#else
# define RUBY_UNTYPED_DATA_WARNING 0
#endif
#define RBIMPL_DATA_FUNC(f) RBIMPL_CAST((void (*)(void *))(f))
#define RBIMPL_ATTRSET_UNTYPED_DATA_FUNC() \
RBIMPL_ATTR_WARNING(("untyped Data is unsafe; use TypedData instead")) \
RBIMPL_ATTR_DEPRECATED(("by TypedData"))
#define RBIMPL_MACRO_SELECT(x, y) x ## y
#define RUBY_MACRO_SELECT(x, y) RBIMPL_MACRO_SELECT(x, y)
/** @endcond */
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RData.
* @return The passed object casted to ::RData.
*/
#define RDATA(obj) RBIMPL_CAST((struct RData *)(obj))
/**
* Convenient getter macro.
*
* @param obj An object, which is in fact an ::RData.
* @return The passed object's ::RData::data field.
*/
#define DATA_PTR(obj) RDATA(obj)->data
/**
* This is a value you can set to ::RData::dfree. Setting this means the data
* was allocated using ::ruby_xmalloc() (or variants), and shall be freed using
* ::ruby_xfree().
*
* @warning Do not use this if you want to use system malloc, because the
* system and Ruby might or might not share the same malloc
* implementation.
*/
#define RUBY_DEFAULT_FREE RBIMPL_DATA_FUNC(-1)
/**
* This is a value you can set to ::RData::dfree. Setting this means the data
* is managed by someone else, like, statically allocated. Of course you are
* on your own then.
*/
#define RUBY_NEVER_FREE RBIMPL_DATA_FUNC(0)
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RUBY_UNTYPED_DATA_FUNC(f) f RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
/*
#define RUBY_DATA_FUNC(func) ((void (*)(void*))(func))
*/
/**
* This is the type of callbacks registered to ::RData. The argument is the
* `data` field.
*/
typedef void (*RUBY_DATA_FUNC)(void*);
/**
* @deprecated
*
* Old "untyped" user data. It has roughly the same usage as struct
* ::RTypedData, but lacked several features such as support for compaction GC.
* Use of this struct is not recommended any longer. If it is dead necessary,
* please inform the core devs about your usage.
*
* @internal
*
* @shyouhei tried to add RBIMPL_ATTR_DEPRECATED for this type but that yielded
* too many warnings in the core. Maybe we want to retry later... Just add
* deprecated document for now.
*/
struct RData {
/** Basic part, including flags and class. */
struct RBasic basic;
/**
* This function is called when the object is experiencing GC marks. If it
* contains references to other Ruby objects, you need to mark them also.
* Otherwise GC will smash your data.
*
* @see rb_gc_mark()
* @warning This is called during GC runs. Object allocations are
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dmark;
/**
* This function is called when the object is no longer used. You need to
* do whatever necessary to avoid memory leaks.
*
* @warning This is called during GC runs. Object allocations are
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dfree;
/** Pointer to the actual C level struct that you want to wrap. */
void *data;
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the primitive way to wrap an existing C struct into ::RData.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] datap Pointer to the target C struct.
* @param[in] dmark Mark function.
* @param[in] dfree Free function.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return An allocated object that wraps `datap`.
*/
VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
/**
* Identical to rb_data_object_wrap(), except it allocates a new data region
* internally instead of taking an existing one. The allocation is done using
* ruby_calloc(). Hence it makes no sense to pass anything other than
* ::RUBY_DEFAULT_FREE to the last argument.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] size Requested size of memory to allocate.
* @param[in] dmark Mark function.
* @param[in] dfree Free function.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return An allocated object that wraps a new `size` byte region.
*/
VALUE rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);
/**
* @private
* Documented in include/ruby/internal/globals.h
*/
RUBY_EXTERN VALUE rb_cObject;
RBIMPL_SYMBOL_EXPORT_END()
/**
* Converts sval, a pointer to your struct, into a Ruby object.
*
* @param klass A ruby level class.
* @param mark Mark function.
* @param free Free function.
* @param sval A pointer to your struct.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
*/
#define Data_Wrap_Struct(klass, mark, free, sval) \
rb_data_object_wrap( \
(klass), \
(sval), \
RBIMPL_DATA_FUNC(mark), \
RBIMPL_DATA_FUNC(free))
/**
* @private
*
* This is an implementation detail of #Data_Make_Struct. People don't use it
* directly.
*
* @param result Variable name of created Ruby object.
* @param klass Ruby level class of the object.
* @param type Type name of the C struct.
* @param size Size of the C struct.
* @param mark Mark function.
* @param free Free function.
* @param sval Variable name of created C struct.
*/
#define Data_Make_Struct0(result, klass, type, size, mark, free, sval) \
VALUE result = rb_data_object_zalloc( \
(klass), \
(size), \
RBIMPL_DATA_FUNC(mark), \
RBIMPL_DATA_FUNC(free)); \
(sval) = RBIMPL_CAST((type *)DATA_PTR(result)); \
RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
/**
* Identical to #Data_Wrap_Struct, except it allocates a new data region
* internally instead of taking an existing one. The allocation is done using
* ruby_calloc(). Hence it makes no sense to pass anything other than
* ::RUBY_DEFAULT_FREE to the `free` argument.
*
* @param klass Ruby level class of the returning object.
* @param type Type name of the C struct.
* @param mark Mark function.
* @param free Free function.
* @param sval Variable name of created C struct.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
*/
#ifdef HAVE_STMT_AND_DECL_IN_EXPR
#define Data_Make_Struct(klass, type, mark, free, sval) \
RB_GNUC_EXTENSION({ \
Data_Make_Struct0( \
data_struct_obj, \
klass, \
type, \
sizeof(type), \
mark, \
free, \
sval); \
data_struct_obj; \
})
#else
#define Data_Make_Struct(klass, type, mark, free, sval) \
rb_data_object_make( \
(klass), \
RBIMPL_DATA_FUNC(mark), \
RBIMPL_DATA_FUNC(free), \
RBIMPL_CAST((void **)&(sval)), \
sizeof(type))
#endif
/**
* Obtains a C struct from inside of a wrapper Ruby object.
*
* @param obj An instance of ::RData.
* @param type Type name of the C struct.
* @param sval Variable name of obtained C struct.
* @return Unwrapped C struct that `obj` holds.
*/
#define Data_Get_Struct(obj, type, sval) \
((sval) = RBIMPL_CAST((type*)rb_data_object_get(obj)))
RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
/**
* @private
*
* This is an implementation detail of rb_data_object_wrap(). People don't use
* it directly.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] ptr Pointer to the target C struct.
* @param[in] mark Mark function.
* @param[in] free Free function.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return An allocated object that wraps `datap`.
*/
static inline VALUE
rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
{
return rb_data_object_wrap(klass, ptr, mark, free);
}
/**
* @private
*
* This is an implementation detail of #Data_Get_Struct. People don't use it
* directly.
*
* @param[in] obj An instance of ::RData.
* @return Unwrapped C struct that `obj` holds.
*/
static inline void *
rb_data_object_get(VALUE obj)
{
Check_Type(obj, RUBY_T_DATA);
return DATA_PTR(obj);
}
RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
/**
* @private
*
* This is an implementation detail of #Data_Get_Struct. People don't use it
* directly.
*
* @param[in] obj An instance of ::RData.
* @return Unwrapped C struct that `obj` holds.
*/
static inline void *
rb_data_object_get_warning(VALUE obj)
{
return rb_data_object_get(obj);
}
#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# define rb_data_object_wrap_warning(klass, ptr, mark, free) \
RB_GNUC_EXTENSION( \
__builtin_choose_expr( \
__builtin_constant_p(klass) && !(klass), \
rb_data_object_wrap(klass, ptr, mark, free), \
(rb_data_object_wrap_warning)(klass, ptr, mark, free)))
#endif
/**
* This is an implementation detail of #Data_Make_Struct. People don't use it
* directly.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] mark_func Mark function.
* @param[in] free_func Free function.
* @param[in] datap Variable of created C struct.
* @param[in] size Requested size of allocation.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
* @post `*datap` holds the created C struct.
*/
static inline VALUE
rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
{
Data_Make_Struct0(result, klass, void, size, mark_func, free_func, *datap);
return result;
}
RBIMPL_ATTR_DEPRECATED(("by: rb_data_object_wrap"))
/** @deprecated This function was renamed to rb_data_object_wrap(). */
static inline VALUE
rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
return rb_data_object_wrap(klass, data, dmark, dfree);
}
/** @cond INTERNAL_MACRO */
#define rb_data_object_wrap_0 rb_data_object_wrap
#define rb_data_object_wrap_1 rb_data_object_wrap_warning
#define rb_data_object_wrap_2 rb_data_object_wrap_ /* Used here vvvv */
#define rb_data_object_wrap RUBY_MACRO_SELECT(rb_data_object_wrap_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_get_0 rb_data_object_get
#define rb_data_object_get_1 rb_data_object_get_warning
#define rb_data_object_get_2 rb_data_object_get_ /* Used here vvvv */
#define rb_data_object_get RUBY_MACRO_SELECT(rb_data_object_get_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_make_0 rb_data_object_make
#define rb_data_object_make_1 rb_data_object_make_warning
#define rb_data_object_make_2 rb_data_object_make_ /* Used here vvvv */
#define rb_data_object_make RUBY_MACRO_SELECT(rb_data_object_make_2, RUBY_UNTYPED_DATA_WARNING)
/** @endcond */
#endif /* RBIMPL_RDATA_H */
include/ruby/internal/core/robject.h 0000644 00000013563 15040330606 0013522 0 ustar 00 #ifndef RBIMPL_ROBJECT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ROBJECT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RObject.
*/
#include "ruby/internal/config.h"
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RObject.
* @return The passed object casted to ::RObject.
*/
#define ROBJECT(obj) RBIMPL_CAST((struct RObject *)(obj))
/** @cond INTERNAL_MACRO */
#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
#define ROBJECT_EMBED ROBJECT_EMBED
#define ROBJECT_IV_CAPACITY ROBJECT_IV_CAPACITY
#define ROBJECT_IVPTR ROBJECT_IVPTR
/** @endcond */
/**
* @private
*
* Bits that you can set to ::RBasic::flags.
*/
enum ruby_robject_flags {
/**
* This flag has something to do with memory footprint. If the object is
* "small" enough, ruby tries to be creative to abuse padding bits of
* struct ::RObject for storing instance variables. This flag denotes that
* situation.
*
* @warning This bit has to be considered read-only. Setting/clearing
* this bit without corresponding fix up must cause immediate
* SEGV. Also, internal structures of an object change
* dynamically and transparently throughout of its lifetime.
* Don't assume it being persistent.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store instance variables. Might better be hidden.
*/
ROBJECT_EMBED = RUBY_FL_USER1
};
#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
*/
enum ruby_robject_consts {
/** Max possible number of instance variables that can be embedded. */
ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
};
#endif
struct st_table;
/**
* Ruby's ordinal objects. Unless otherwise special cased, all predefined and
* user-defined classes share this struct to hold their instances.
*/
struct RObject {
/** Basic part, including flags and class. */
struct RBasic basic;
/** Object's specific fields. */
union {
/**
* Object that use separated memory region for instance variables use
* this pattern.
*/
struct {
/** Pointer to a C array that holds instance variables. */
VALUE *ivptr;
/**
* This is a table that holds instance variable name to index
* mapping. Used when accessing instance variables using names.
*
* @internal
*
* This is a shortcut for `RCLASS_IV_INDEX_TBL(rb_obj_class(obj))`.
*/
struct rb_id_table *iv_index_tbl;
} heap;
#if USE_RVARGC
/* Embedded instance variables. When an object is small enough, it
* uses this area to store the instance variables.
*
* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
VALUE ary[1];
#else
/**
* Embedded instance variables. When an object is small enough, it
* uses this area to store the instance variables.
*/
VALUE ary[ROBJECT_EMBED_LEN_MAX];
#endif
} as;
};
/* Offsets for YJIT */
#ifndef __cplusplus
static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = offsetof(struct RObject, as.heap.ivptr);
static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = offsetof(struct RObject, as.heap.iv_index_tbl);
static const int32_t ROBJECT_OFFSET_AS_ARY = offsetof(struct RObject, as.ary);
#endif
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the instance variables.
*
* @param[in] obj Object in question.
* @return Its instance variables, in C array.
* @pre `obj` must be an instance of ::RObject.
*
* @internal
*
* @shyouhei finds no reason for this to be visible from extension libraries.
*/
static inline VALUE *
ROBJECT_IVPTR(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
struct RObject *const ptr = ROBJECT(obj);
if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
return ptr->as.ary;
}
else {
return ptr->as.heap.ivptr;
}
}
#endif /* RBIMPL_ROBJECT_H */
include/ruby/internal/core/rbasic.h 0000644 00000012467 15040330606 0013337 0 ustar 00 #ifndef RBIMPL_RBASIC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RBASIC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RBasic.
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
/**
* Convenient casting macro.
*
* @param obj Arbitrary Ruby object.
* @return The passed object casted to ::RBasic.
*/
#define RBASIC(obj) RBIMPL_CAST((struct RBasic *)(obj))
/** @cond INTERNAL_MACRO */
#define RBASIC_CLASS RBASIC_CLASS
#define RBIMPL_RVALUE_EMBED_LEN_MAX 3
#define RVALUE_EMBED_LEN_MAX RVALUE_EMBED_LEN_MAX
#define RBIMPL_EMBED_LEN_MAX_OF(T) \
RBIMPL_CAST((int)(sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]) / (sizeof(T))))
/** @endcond */
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
*/
enum ruby_rvalue_flags {
/** Max possible number of objects that can be embedded. */
RVALUE_EMBED_LEN_MAX = RBIMPL_RVALUE_EMBED_LEN_MAX
};
/**
* Ruby's object's, base components. Every single ruby objects have them in
* common.
*/
struct
RUBY_ALIGNAS(SIZEOF_VALUE)
RBasic {
/**
* Per-object flags. Each ruby objects have their own characteristics
* apart from their classes. For instance whether an object is frozen or
* not is not controlled by its class. This is where such properties are
* stored.
*
* @see enum ::ruby_fl_type
*
* @note This is ::VALUE rather than an enum for alignment purpose. Back
* in the 1990s there were no such thing like `_Alignas` in C.
*/
VALUE flags;
/**
* Class of an object. Every object has its class. Also, everything is an
* object in Ruby. This means classes are also objects. Classes have
* their own classes, classes of classes have their classes, too ... and
* it recursively continues forever.
*
* Also note the `const` qualifier. In ruby an object cannot "change" its
* class.
*/
const VALUE klass;
#ifdef __cplusplus
public:
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_FORCEINLINE()
RBIMPL_ATTR_NOALIAS()
/**
* We need to define this explicit constructor because the field `klass` is
* const-qualified above, which effectively defines the implicit default
* constructor as "deleted" (as of C++11) -- No way but to define one by
* ourselves.
*/
RBasic() :
flags(RBIMPL_VALUE_NULL),
klass(RBIMPL_VALUE_NULL)
{
}
#endif
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Make the object invisible from Ruby code.
*
* It is useful to let Ruby's GC manage your internal data structure -- The
* object keeps being managed by GC, but `ObjectSpace.each_object` never yields
* the object.
*
* Note that the object also lose a way to call a method on it.
*
* @param[out] obj A Ruby object.
* @return The passed object.
* @post The object is destructively modified to be invisible.
* @see rb_obj_reveal
*/
VALUE rb_obj_hide(VALUE obj);
/**
* Make a hidden object visible again.
*
* It is the caller's responsibility to pass the right `klass` which `obj`
* originally used to belong to.
*
* @param[out] obj A Ruby object.
* @param[in] klass Class of `obj`.
* @return Passed `obj`.
* @pre `obj` was previously hidden.
* @post `obj`'s class is `klass`.
* @see rb_obj_hide
*/
VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the class of an object.
*
* @param[in] obj An object.
* @return Its class.
*/
static inline VALUE
RBASIC_CLASS(VALUE obj)
{
RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
return RBASIC(obj)->klass;
}
#endif /* RBIMPL_RBASIC_H */
include/ruby/internal/core/rclass.h 0000644 00000006716 15040330606 0013363 0 ustar 00 #ifndef RBIMPL_RCLASS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RCLASS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate struct RClass.
* @note The struct RClass itself is opaque.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/cast.h"
/** @cond INTERNAL_MACRO */
#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
/** @endcond */
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an RClass.
* @return The passed object casted to RClass.
*/
#define RCLASS(obj) RBIMPL_CAST((struct RClass *)(obj))
/** @alias{RCLASS} */
#define RMODULE RCLASS
/** @alias{rb_class_get_superclass} */
#define RCLASS_SUPER rb_class_get_superclass
/**
* @private
*
* Bits that you can set to ::RBasic::flags.
*
* @internal
*
* Why is it here, given RClass itself is not?
*/
enum ruby_rmodule_flags {
/**
* This flag has something to do with refinements. A module created using
* rb_mod_refine() has this flag set. This is the bit which controls
* difference between normal inclusion versus refinements.
*/
RMODULE_IS_REFINEMENT = RUBY_FL_USER3
};
struct RClass; /* Opaque, declared here for RCLASS() macro. */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Returns the superclass of a class.
* @param[in] klass An object of RClass.
* @retval RUBY_Qfalse `klass` has no super class.
* @retval otherwise Raw superclass of `klass`
* @see rb_class_superclass
*
* ### Q&A ###
*
* - Q: How can a class have no super class?
*
* - A: `klass` could be a module. Or it could be ::rb_cBasicObject.
*
* - Q: What do you mean by "raw" superclass?
*
* - A: This is a really good question. The answer is that this function
* returns something different from what you would normally expect. On
* occasions ruby inserts hidden classes in a hierarchy of class
* inheritance behind-the-scene. Such classes are called "iclass"es and
* distinguished using ::RUBY_T_ICLASS in C level. They are truly
* transparent from Ruby level but can be accessed from C, by using this
* API.
*/
VALUE rb_class_get_superclass(VALUE klass);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_RCLASS_H */
include/ruby/internal/core/rmatch.h 0000644 00000012501 15040330606 0013337 0 ustar 00 #ifndef RBIMPL_RMATCH_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RMATCH_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RMatch.
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RMatch.
* @return The passed object casted to ::RMatch.
*/
#define RMATCH(obj) RBIMPL_CAST((struct RMatch *)(obj))
/** @cond INTERNAL_MACRO */
#define RMATCH_REGS RMATCH_REGS
/** @endcond */
struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
struct re_registers; /* Also in onigmo.h */
/**
* @old{re_pattern_buffer}
*
* @internal
*
* @shyouhei wonders: is anyone actively using this typedef ...?
*/
typedef struct re_pattern_buffer Regexp;
/**
* Represents the region of a capture group. This is basically for caching
* purpose. re_registers have similar concepts (`beg` and `end`) but they are
* in `ptrdiff_t*`. In order for us to implement `MatchData#offset` that info
* has to be converted to offset integers. This is the struct to hold such
* things.
*
* @internal
*
* But why on earth it has to be visible from extension libraries?
*/
struct rmatch_offset {
long beg; /**< Beginning of a group. */
long end; /**< End of a group. */
};
/** Represents a match. */
struct rmatch {
/**
* "Registers" of a match. This is a quasi-opaque struct that holds
* execution result of a match. Roughly resembles `&~`.
*/
struct re_registers regs;
/** Capture group offsets, in C array. */
struct rmatch_offset *char_offset;
/** Number of ::rmatch_offset that ::rmatch::char_offset holds. */
int char_offset_num_allocated;
};
/**
* Regular expression execution context. When a regular expression "matches"
* to a string, it generates capture groups etc. This struct holds that info.
* Visible from Ruby as an instance of `MatchData`.
*
* @note There is no way for extension libraries to manually generate this
* struct except by actually exercising the match operation of a regular
* expression.
*/
struct RMatch {
/** Basic part, including flags and class. */
struct RBasic basic;
/**
* The target string that the match was made against.
*/
VALUE str;
/**
* The result of this match.
*/
struct rmatch *rmatch;
/**
* The expression of this match.
*/
VALUE regexp; /* RRegexp */
};
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the raw ::re_registers.
*
* @param[in] match A match object
* @pre `match` must be of ::RMatch.
* @return Its execution result.
* @note Good. So you are aware of the fact that it could return NULL.
* Yes. It actually does. This is a really bizarre thing. The
* situation is about `String#gsub` and its family. They take
* strings as arguments, like `"foo".sub("bar", "baz")`. On such
* situations, in order to optimise memory allocations, these
* methods do not involve regular expressions at all. They just
* sequentially scan the receiver. Okay. The story begins here.
* Even when they do not kick our regexp engine, there must be
* backref objects e.g. `$&`. But how? You know what? Ruby fakes
* them. It allocates an empty ::RMatch and behaves as if there
* were execution contexts. In reality there weren't. No
* ::re_registers are allocated then. There is no way for this
* function but to return NULL for those fake ::RMatch. This is
* the reason for the nullability of this function.
*/
static inline struct re_registers *
RMATCH_REGS(VALUE match)
{
RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
RBIMPL_ASSERT_OR_ASSUME(RMATCH(match)->rmatch != NULL);
return &RMATCH(match)->rmatch->regs;
}
#endif /* RBIMPL_RMATCH_H */
include/ruby/internal/core/rstring.h 0000644 00000047016 15040330606 0013562 0 ustar 00 #ifndef RBIMPL_RSTRING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RSTRING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RString.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/warning_push.h"
#include "ruby/assert.h"
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RString.
* @return The passed object casted to ::RString.
*/
#define RSTRING(obj) RBIMPL_CAST((struct RString *)(obj))
/** @cond INTERNAL_MACRO */
#define RSTRING_NOEMBED RSTRING_NOEMBED
#if !USE_RVARGC
#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
#endif
#define RSTRING_FSTR RSTRING_FSTR
#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
#define RSTRING_LEN RSTRING_LEN
#define RSTRING_LENINT RSTRING_LENINT
#define RSTRING_PTR RSTRING_PTR
#define RSTRING_END RSTRING_END
/** @endcond */
/**
* @name Conversion of Ruby strings into C's
*
* @{
*/
/**
* Ensures that the parameter object is a String. This is done by calling its
* `to_str` method.
*
* @param[in,out] v Arbitrary Ruby object.
* @exception rb_eTypeError No implicit conversion defined.
* @post `v` is a String.
*/
#define StringValue(v) rb_string_value(&(v))
/**
* Identical to #StringValue, except it returns a `char*`.
*
* @param[in,out] v Arbitrary Ruby object.
* @exception rb_eTypeError No implicit conversion defined.
* @return Converted Ruby string's backend C string.
* @post `v` is a String.
*/
#define StringValuePtr(v) rb_string_value_ptr(&(v))
/**
* Identical to #StringValuePtr, except it additionally checks for the contents
* for viability as a C string. Ruby can accept wider range of contents as
* strings, compared to C. This function is to check that.
*
* @param[in,out] v Arbitrary Ruby object.
* @exception rb_eTypeError No implicit conversion defined.
* @exception rb_eArgError String is not C-compatible.
* @return Converted Ruby string's backend C string.
* @post `v` is a String.
*/
#define StringValueCStr(v) rb_string_value_cstr(&(v))
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define SafeStringValue(v) StringValue(v)
/**
* Identical to #StringValue, except it additionally converts the string's
* encoding to default external encoding. Ruby has a concept called encodings.
* A string can have different encoding than the environment expects. Someone
* has to make sure its contents be converted to something suitable. This is
* that routine. Call it when necessary.
*
* @param[in,out] v Arbitrary Ruby object.
* @exception rb_eTypeError No implicit conversion defined.
* @return Converted Ruby string's backend C string.
* @post `v` is a String.
*
* @internal
*
* Not sure but it seems this macro does not raise on encoding
* incompatibilities? Doesn't sound right to @shyouhei.
*/
#define ExportStringValue(v) do { \
StringValue(v); \
(v) = rb_str_export(v); \
} while (0)
/** @} */
/**
* @private
*
* Bits that you can set to ::RBasic::flags.
*
* @warning These enums are not the only bits we use for strings.
*
* @internal
*
* Actually all bits through FL_USER1 to FL_USER19 are used for strings. Why
* only this tiny part of them are made public here? @shyouhei can find no
* reason.
*/
enum ruby_rstring_flags {
/**
* This flag has something to do with memory footprint. If the string is
* short enough, ruby tries to be creative to abuse padding bits of struct
* ::RString for storing contents. If this flag is set that string does
* _not_ do that, to resort to good old fashioned external allocation
* strategy instead.
*
* @warning This bit has to be considered read-only. Setting/clearing
* this bit without corresponding fix up must cause immediate
* SEGV. Also, internal structures of a string change
* dynamically and transparently throughout of its lifetime.
* Don't assume it being persistent.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store a string. Might better be hidden.
*/
RSTRING_NOEMBED = RUBY_FL_USER1,
#if !USE_RVARGC
/**
* When a string employs embedded strategy (see ::RSTRING_NOEMBED), these
* bits are used to store the number of bytes actually filled into
* ::RString::ary.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store a string. Might better be hidden.
*/
RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
RUBY_FL_USER5 | RUBY_FL_USER6,
#endif
/* Actually, string encodings are also encoded into the flags, using
* remaining bits.*/
/**
* This flag has something to do with infamous "f"string. What is a
* fstring? Well it is a special subkind of strings that is immutable,
* deduped globally, and managed by our GC. It is much like a Symbol (in
* fact Symbols are dynamic these days and are backended using fstrings).
* This concept has been silently introduced at some point in 2.x era.
* Since then it gained wider acceptance in the core. But extension
* libraries could not know that until very recently. Strings of this flag
* live in a special Limbo deep inside of the interpreter. Never try to
* manipulate it by hand.
*
* @internal
*
* Fstrings are not the only variant strings that we implement today.
* Other things are behind-the-scene. This is the only one that is visible
* from extension library. There is no clear reason why it has to be.
* Given there are more "polite" ways to create fstrings, it seems this bit
* need not be exposed to extension libraries. Might better be hidden.
*/
RSTRING_FSTR = RUBY_FL_USER17
};
#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
*/
enum ruby_rstring_consts {
/** Where ::RSTRING_EMBED_LEN_MASK resides. */
RSTRING_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 2,
/** Max possible number of characters that can be embedded. */
RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
};
#endif
/**
* Ruby's String. A string in ruby conceptually has these information:
*
* - Encoding of the string.
* - Length of the string.
* - Contents of the string.
*
* It is worth noting that a string is _not_ an array of characters in ruby.
* It has never been. In 1.x a string was an array of integers. Since 2.x a
* string is no longer an array of anything. A string is a string -- just like
* a Time is not an integer.
*/
struct RString {
/** Basic part, including flags and class. */
struct RBasic basic;
/** String's specific fields. */
union {
/**
* Strings that use separated memory region for contents use this
* pattern.
*/
struct {
/**
* Length of the string, not including terminating NUL character.
*
* @note This is in bytes.
*/
long len;
/**
* Pointer to the contents of the string. In the old days each
* string had dedicated memory regions. That is no longer true
* today, but there still are strings of such properties. This
* field could be used to point such things.
*/
char *ptr;
/** Auxiliary info. */
union {
/**
* Capacity of `*ptr`. A continuous memory region of at least
* `capa` bytes is expected to exist at `*ptr`. This can be
* bigger than `len`.
*/
long capa;
/**
* Parent of the string. Nowadays strings can share their
* contents each other, constructing gigantic nest of objects.
* This situation is called "shared", and this is the field to
* control such properties.
*/
VALUE shared;
} aux;
} heap;
/** Embedded contents. */
struct {
#if USE_RVARGC
long len;
/* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
char ary[1];
#else
/**
* When a string is short enough, it uses this area to store the
* contents themselves. This was impractical in the 20th century,
* but these days 64 bit machines can typically hold 24 bytes here.
* Could be sufficiently large. In this case the length is encoded
* into the flags.
*/
char ary[RSTRING_EMBED_LEN_MAX + 1];
#endif
} embed;
} as;
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Identical to rb_check_string_type(), except it raises exceptions in case of
* conversion failures.
*
* @param[in] obj Target object.
* @exception rb_eTypeError No implicit conversion to String.
* @return Return value of `obj.to_str`.
* @see rb_io_get_io
* @see rb_ary_to_ary
*/
VALUE rb_str_to_str(VALUE obj);
/**
* Identical to rb_str_to_str(), except it fills the passed pointer with the
* converted object.
*
* @param[in,out] ptr Pointer to a variable of target object.
* @exception rb_eTypeError No implicit conversion to String.
* @return Return value of `obj.to_str`.
* @post `*ptr` is the return value.
*/
VALUE rb_string_value(volatile VALUE *ptr);
/**
* Identical to rb_str_to_str(), except it returns the converted string's
* backend memory region.
*
* @param[in,out] ptr Pointer to a variable of target object.
* @exception rb_eTypeError No implicit conversion to String.
* @post `*ptr` is the return value of `obj.to_str`.
* @return Pointer to the contents of the return value.
*/
char *rb_string_value_ptr(volatile VALUE *ptr);
/**
* Identical to rb_string_value_ptr(), except it additionally checks for the
* contents for viability as a C string. Ruby can accept wider range of
* contents as strings, compared to C. This function is to check that.
*
* @param[in,out] ptr Pointer to a variable of target object.
* @exception rb_eTypeError No implicit conversion to String.
* @exception rb_eArgError String is not C-compatible.
* @post `*ptr` is the return value of `obj.to_str`.
* @return Pointer to the contents of the return value.
*/
char *rb_string_value_cstr(volatile VALUE *ptr);
/**
* Identical to rb_str_to_str(), except it additionally converts the string
* into default external encoding. Ruby has a concept called encodings. A
* string can have different encoding than the environment expects. Someone
* has to make sure its contents be converted to something suitable. This is
* that routine. Call it when necessary.
*
* @param[in] obj Target object.
* @exception rb_eTypeError No implicit conversion to String.
* @return Converted ruby string of default external encoding.
*/
VALUE rb_str_export(VALUE obj);
/**
* Identical to rb_str_export(), except it converts into the locale encoding
* instead.
*
* @param[in] obj Target object.
* @exception rb_eTypeError No implicit conversion to String.
* @return Converted ruby string of locale encoding.
*/
VALUE rb_str_export_locale(VALUE obj);
RBIMPL_ATTR_ERROR(("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead"))
/**
* @private
*
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*/
void rb_check_safe_str(VALUE);
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define Check_SafeStr(v) rb_check_safe_str(RBIMPL_CAST((VALUE)(v)))
/**
* @private
*
* Prints diagnostic message to stderr when RSTRING_PTR or RSTRING_END
* is NULL.
*
* @param[in] func The function name where encountered NULL pointer.
*/
void rb_debug_rstring_null_ptr(const char *func);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the length of the string.
*
* @param[in] str String in question.
* @return Its length, in bytes.
* @pre `str` must be an instance of ::RString, and must has its
* ::RSTRING_NOEMBED flag off.
*
* @internal
*
* This was a macro before. It was inevitable to be public, since macros are
* global constructs. But should it be forever? Now that it is a function,
* @shyouhei thinks it could just be eliminated, hidden into implementation
* details.
*/
static inline long
RSTRING_EMBED_LEN(VALUE str)
{
RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
#if USE_RVARGC
long f = RSTRING(str)->as.embed.len;
return f;
#else
VALUE f = RBASIC(str)->flags;
f &= RSTRING_EMBED_LEN_MASK;
f >>= RSTRING_EMBED_LEN_SHIFT;
return RBIMPL_CAST((long)f);
#endif
}
RBIMPL_WARNING_PUSH()
#if RBIMPL_COMPILER_IS(Intel)
RBIMPL_WARNING_IGNORED(413)
#endif
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
* "Expands" an embedded string into an ordinal one. This is a function that
* returns aggregated type. The returned struct always has its `as.heap.len`
* an `as.heap.ptr` fields set appropriately.
*
* This is an implementation detail that 3rd parties should never bother.
*/
static inline struct RString
rbimpl_rstring_getmem(VALUE str)
{
RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
return *RSTRING(str);
}
else {
/* Expecting compilers to optimize this on-stack struct away. */
struct RString retval;
retval.as.heap.len = RSTRING_EMBED_LEN(str);
retval.as.heap.ptr = RSTRING(str)->as.embed.ary;
return retval;
}
}
RBIMPL_WARNING_POP()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the length of the string.
*
* @param[in] str String in question.
* @return Its length, in bytes.
* @pre `str` must be an instance of ::RString.
*/
static inline long
RSTRING_LEN(VALUE str)
{
return rbimpl_rstring_getmem(str).as.heap.len;
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the contents pointer of the string.
*
* @param[in] str String in question.
* @return Pointer to its contents.
* @pre `str` must be an instance of ::RString.
*/
static inline char *
RSTRING_PTR(VALUE str)
{
char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
if (RB_UNLIKELY(! ptr)) {
/* :BEWARE: @shyouhei thinks that currently, there are rooms for this
* function to return NULL. In the 20th century that was a pointless
* concern. However struct RString can hold fake strings nowadays. It
* seems no check against NULL are exercised around handling of them
* (one of such usages is located in marshal.c, which scares
* @shyouhei). Better check here for maximum safety.
*
* Also, this is not rb_warn() because RSTRING_PTR() can be called
* during GC (see what obj_info() does). rb_warn() needs to allocate
* Ruby objects. That is not possible at this moment. */
rb_debug_rstring_null_ptr("RSTRING_PTR");
}
return ptr;
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the end of the contents pointer of the string.
*
* @param[in] str String in question.
* @return Pointer to its end of contents.
* @pre `str` must be an instance of ::RString.
*/
static inline char *
RSTRING_END(VALUE str)
{
struct RString buf = rbimpl_rstring_getmem(str);
if (RB_UNLIKELY(! buf.as.heap.ptr)) {
/* Ditto. */
rb_debug_rstring_null_ptr("RSTRING_END");
}
return &buf.as.heap.ptr[buf.as.heap.len];
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to RSTRING_LEN(), except it differs for the return type.
*
* @param[in] str String in question.
* @exception rb_eRangeError Too long.
* @return Its length, in bytes.
* @pre `str` must be an instance of ::RString.
*
* @internal
*
* This API seems redundant but has actual usages.
*/
static inline int
RSTRING_LENINT(VALUE str)
{
return rb_long2int(RSTRING_LEN(str));
}
/**
* Convenient macro to obtain the contents and length at once.
*
* @param str String in question.
* @param ptrvar Variable where its contents is stored.
* @param lenvar Variable where its length is stored.
*/
#ifdef HAVE_STMT_AND_DECL_IN_EXPR
# define RSTRING_GETMEM(str, ptrvar, lenvar) \
__extension__ ({ \
struct RString rbimpl_str = rbimpl_rstring_getmem(str); \
(ptrvar) = rbimpl_str.as.heap.ptr; \
(lenvar) = rbimpl_str.as.heap.len; \
})
#else
# define RSTRING_GETMEM(str, ptrvar, lenvar) \
((ptrvar) = RSTRING_PTR(str), \
(lenvar) = RSTRING_LEN(str))
#endif /* HAVE_STMT_AND_DECL_IN_EXPR */
#endif /* RBIMPL_RSTRING_H */
include/ruby/internal/core/rhash.h 0000644 00000011466 15040330606 0013177 0 ustar 00 #ifndef RBIMPL_RHASH_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RHASH_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate struct RHash.
* @note The struct RHash itself is opaque.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif
/**
* Retrieves the internal table.
*
* @param[in] h An instance of RHash.
* @pre `h` must be of ::RUBY_T_HASH.
* @return A struct st_table which has the contents of this hash.
* @note Nowadays as Ruby evolved over ages, RHash has multiple backend
* storage engines. `h`'s backend is not guaranteed to be a
* st_table. This function creates one when necessary.
*/
#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* Declaration of rb_hash_iter_lev() is at include/ruby/backward.h.
*/
#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* Declaration of rb_hash_ifnone() is at include/ruby/backward.h.
*/
#define RHASH_IFNONE(h) rb_hash_ifnone(h)
/**
* Queries the size of the hash. Size here means the number of keys that the
* hash stores.
*
* @param[in] h An instance of RHash.
* @pre `h` must be of ::RUBY_T_HASH.
* @return The size of the hash.
*/
#define RHASH_SIZE(h) rb_hash_size_num(h)
/**
* Checks if the hash is empty.
*
* @param[in] h An instance of RHash.
* @pre `h` must be of ::RUBY_T_HASH.
* @retval true It is.
* @retval false It isn't.
*/
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
/**
* Destructively updates the default value of the hash.
*
* @param[out] h An instance of RHash.
* @param[in] ifnone Arbitrary default value.
* @pre `h` must be of ::RUBY_T_HASH.
*
* @internal
*
* But why you can set this, given rb_hash_ifnone() doesn't exist?
*/
#define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)
struct st_table; /* in ruby/st.h */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the implementation detail of #RHASH_SIZE. People don't call this
* directly.
*
* @param[in] hash An instance of RHash.
* @pre `hash` must be of ::RUBY_T_HASH.
* @return The size of the hash.
*/
size_t rb_hash_size_num(VALUE hash);
/**
* This is the implementation detail of #RHASH_TBL. People don't call this
* directly.
*
* @param[in] hash An instance of RHash.
* @param[in] file The `__FILE__`.
* @param[in] line The `__LINE__`.
* @pre `hash` must be of ::RUBY_T_HASH.
* @return Table that has the contents of the hash.
*/
struct st_table *rb_hash_tbl(VALUE hash, const char *file, int line);
/**
* This is the implementation detail of #RHASH_SET_IFNONE. People don't call
* this directly.
*
* @param[out] hash An instance of RHash.
* @param[in] ifnone Arbitrary default value.
* @pre `hash` must be of ::RUBY_T_HASH.
*/
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_RHASH_H */
include/ruby/internal/core/rbignum.h 0000644 00000005605 15040330606 0013533 0 ustar 00 #ifndef RBIMPL_RBIGNUM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RBIGNUM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate struct RBignum.
* @note The struct RBignum itself is opaque.
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/stdbool.h"
#define RBIGNUM_SIGN rb_big_sign /**< @alias{rb_big_sign} */
/** @cond INTERNAL_MACRO */
#define RBIGNUM_POSITIVE_P RBIGNUM_POSITIVE_P
#define RBIGNUM_NEGATIVE_P RBIGNUM_NEGATIVE_P
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* The "sign" of a bignum.
*
* @param[in] num An object of RBignum.
* @retval 1 It is greater than or equal to zero.
* @retval 0 It is less than zero.
*
* @internal
*
* Implementation wise, unlike fixnums (which are 2's complement), bignums are
* signed magnitude system. Theoretically it could be possible to have
* negative zero instances. But in reality there is no way to create such
* thing. Nobody ever needed that kind of insanity.
*/
int rb_big_sign(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()
/**
* Checks if the bignum is positive.
* @param[in] b An object of RBignum.
* @retval false `b` is less than zero.
* @retval true Otherwise.
*/
static inline bool
RBIGNUM_POSITIVE_P(VALUE b)
{
RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
return RBIGNUM_SIGN(b);
}
/**
* Checks if the bignum is negative.
* @param[in] b An object of RBignum.
* @retval true `b` is less than zero.
* @retval false Otherwise.
*/
static inline bool
RBIGNUM_NEGATIVE_P(VALUE b)
{
RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
return ! RBIGNUM_POSITIVE_P(b);
}
#endif /* RBIMPL_RBIGNUM_H */
include/ruby/internal/core/rstruct.h 0000644 00000010153 15040330606 0013570 0 ustar 00 #ifndef RBIMPL_RSTRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RSTRUCT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Routines to manipulate struct RStruct.
* @note The struct RStruct itself is opaque.
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/int.h"
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* Declaration of rb_struct_ptr() is at include/ruby/backward.h.
*/
#define RSTRUCT_PTR(st) rb_struct_ptr(st)
/** @cond INTERNAL_MACRO */
#define RSTRUCT_LEN RSTRUCT_LEN
#define RSTRUCT_SET RSTRUCT_SET
#define RSTRUCT_GET RSTRUCT_GET
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Returns the number of struct members.
*
* @param[in] st An instance of RStruct.
* @return The number of members of `st`.
* @pre `st` must be of ::RUBY_T_STRUCT.
*/
VALUE rb_struct_size(VALUE st);
/**
* Resembles `Struct#[]`.
*
* @param[in] st An instance of RStruct.
* @param[in] k Index a.k.a. key of the struct.
* @exception rb_eTypeError `k` is neither Numeric, Symbol, nor String.
* @exception rb_eIndexError Numerical index out of range.
* @exception rb_eNameError No such key.
* @return The member stored at `k` in `st`.
* @pre `st` must be of ::RUBY_T_STRUCT.
*/
VALUE rb_struct_aref(VALUE st, VALUE k);
/**
* Resembles `Struct#[]=`.
*
* @param[out] st An instance of RStruct.
* @param[in] k Index a.k.a. key of the struct.
* @param[in] v Value to store.
* @exception rb_eTypeError `k` is neither Numeric, Symbol, nor String.
* @exception rb_eIndexError Numerical index out of range.
* @exception rb_eNameError No such key.
* @return Passed `v`.
* @pre `st` must be of ::RUBY_T_STRUCT.
* @post `v` is stored at `k` in `st`.
*/
VALUE rb_struct_aset(VALUE st, VALUE k, VALUE v);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_size() */
static inline long
RSTRUCT_LEN(VALUE st)
{
RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
return RB_NUM2LONG(rb_struct_size(st));
}
RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_aset() */
static inline VALUE
RSTRUCT_SET(VALUE st, int k, VALUE v)
{
RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
return rb_struct_aset(st, INT2NUM(k), (v));
}
RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_aref() */
static inline VALUE
RSTRUCT_GET(VALUE st, int k)
{
RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);
return rb_struct_aref(st, INT2NUM(k));
}
#endif /* RBIMPL_RSTRUCT_H */
include/ruby/internal/core/rregexp.h 0000644 00000013002 15040330606 0013532 0 ustar 00 #ifndef RBIMPL_RREGEXP_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RREGEXP_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RRegexp.
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RRegexp.
* @return The passed object casted to ::RRegexp.
*/
#define RREGEXP(obj) RBIMPL_CAST((struct RRegexp *)(obj))
/**
* Convenient accessor macro.
*
* @param obj An object, which is in fact an ::RRegexp.
* @return The passed object's pattern buffer.
*/
#define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr)
/** @cond INTERNAL_MACRO */
#define RREGEXP_SRC RREGEXP_SRC
#define RREGEXP_SRC_PTR RREGEXP_SRC_PTR
#define RREGEXP_SRC_LEN RREGEXP_SRC_LEN
#define RREGEXP_SRC_END RREGEXP_SRC_END
/** @endcond */
struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
/**
* Ruby's regular expression. A regexp is compiled into its own intermediate
* representation. This one holds that info. Regexp "match" operation then
* executes that IR.
*/
struct RRegexp {
/** Basic part, including flags and class. */
struct RBasic basic;
/**
* The pattern buffer. This is a quasi-opaque struct that holds compiled
* intermediate representation of the regular expression.
*
* @note Compilation of a regexp could be delayed until actual match.
*/
struct re_pattern_buffer *ptr;
/** Source code of this expression. */
const VALUE src;
/**
* Reference count. A regexp match can take extraordinarily long time to
* run. Ruby's regular expression is heavily extended and not a regular
* language any longer; runs in NP-time in practice. Now, Ruby also has
* threads and GVL. In order to prevent long GVL lockup, our regexp engine
* can release it on occasions. This means that multiple threads can touch
* a regular expressions at once. That itself is okay. But their cleanup
* phase shall wait for all the concurrent runs, to prevent use-after-free
* situation. This field is used to count such threads that are executing
* this particular pattern buffer.
*
* @warning Of course, touching this field from extension libraries causes
* catastrophic effects. Just leave it.
*/
unsigned long usecnt;
};
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Convenient getter function.
*
* @param[in] rexp The regular expression in question.
* @return The source code of the regular expression.
* @pre `rexp` must be of ::RRegexp.
*/
static inline VALUE
RREGEXP_SRC(VALUE rexp)
{
RBIMPL_ASSERT_TYPE(rexp, RUBY_T_REGEXP);
VALUE ret = RREGEXP(rexp)->src;
RBIMPL_ASSERT_TYPE(ret, RUBY_T_STRING);
return ret;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Convenient getter function.
*
* @param[in] rexp The regular expression in question.
* @return The source code of the regular expression, in C's string.
* @pre `rexp` must be of ::RRegexp.
*
* @internal
*
* It seems nobody uses this function in the wild. Subject to hide?
*/
static inline char *
RREGEXP_SRC_PTR(VALUE rexp)
{
return RSTRING_PTR(RREGEXP_SRC(rexp));
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Convenient getter function.
*
* @param[in] rexp The regular expression in question.
* @return The length of the source code of the regular expression.
* @pre `rexp` must be of ::RRegexp.
*
* @internal
*
* It seems nobody uses this function in the wild. Subject to hide?
*/
static inline long
RREGEXP_SRC_LEN(VALUE rexp)
{
return RSTRING_LEN(RREGEXP_SRC(rexp));
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Convenient getter function.
*
* @param[in] rexp The regular expression in question.
* @return The end of the source code of the regular expression.
* @pre `rexp` must be of ::RRegexp.
*
* @internal
*
* It seems nobody uses this function in the wild. Subject to hide?
*/
static inline char *
RREGEXP_SRC_END(VALUE rexp)
{
return RSTRING_END(RREGEXP_SRC(rexp));
}
#endif /* RBIMPL_RREGEXP_H */
include/ruby/internal/core/rarray.h 0000644 00000043705 15040330606 0013373 0 ustar 00 #ifndef RBIMPL_RARRAY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RARRAY_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RArray.
*/
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/rgengc.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"
/**
* @private
* @warning Do not touch this macro.
* @warning It is an implementation detail.
* @warning The value of this macro must match for ruby itself and all
* extension libraries, otherwise serious memory corruption shall
* occur.
*/
#ifndef USE_TRANSIENT_HEAP
# define USE_TRANSIENT_HEAP 1
#endif
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RArray.
* @return The passed object casted to ::RArray.
*/
#define RARRAY(obj) RBIMPL_CAST((struct RArray *)(obj))
/** @cond INTERNAL_MACRO */
#define RARRAY_EMBED_FLAG RARRAY_EMBED_FLAG
#define RARRAY_EMBED_LEN_MASK RARRAY_EMBED_LEN_MASK
#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
#if USE_TRANSIENT_HEAP
# define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
#else
# define RARRAY_TRANSIENT_FLAG 0
#endif
/** @endcond */
#define RARRAY_LEN rb_array_len /**< @alias{rb_array_len} */
#define RARRAY_CONST_PTR rb_array_const_ptr /**< @alias{rb_array_const_ptr} */
#define RARRAY_CONST_PTR_TRANSIENT rb_array_const_ptr_transient /**< @alias{rb_array_const_ptr_transient} */
/** @cond INTERNAL_MACRO */
#if defined(__fcc__) || defined(__fcc_version) || \
defined(__FCC__) || defined(__FCC_VERSION)
/* workaround for old version of Fujitsu C Compiler (fcc) */
# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
#else
# define FIX_CONST_VALUE_PTR(x) (x)
#endif
#define RARRAY_EMBED_LEN RARRAY_EMBED_LEN
#define RARRAY_LENINT RARRAY_LENINT
#define RARRAY_TRANSIENT_P RARRAY_TRANSIENT_P
#define RARRAY_ASET RARRAY_ASET
#define RARRAY_PTR RARRAY_PTR
/** @endcond */
/**
* @private
*
* Bits that you can set to ::RBasic::flags.
*
* @warning These enums are not the only bits we use for arrays.
*
* @internal
*
* Unlike strings, flag usages for arrays are scattered across the entire
* source codes. @shyouhei doesn't know the complete list. But what is listed
* here is at least incomplete.
*/
enum ruby_rarray_flags {
/**
* This flag has something to do with memory footprint. If the array is
* "small" enough, ruby tries to be creative to abuse padding bits of
* struct ::RArray for storing its contents. This flag denotes that
* situation.
*
* @warning This bit has to be considered read-only. Setting/clearing
* this bit without corresponding fix up must cause immediate
* SEGV. Also, internal structures of an array change
* dynamically and transparently throughout of its lifetime.
* Don't assume it being persistent.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store array elements. It was a bad idea to expose this to them.
*/
RARRAY_EMBED_FLAG = RUBY_FL_USER1,
/* RUBY_FL_USER2 is for ELTS_SHARED */
/**
* When an array employs embedded strategy (see ::RARRAY_EMBED_FLAG), these
* bits are used to store the number of elements actually filled into
* ::RArray::ary.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store array elements. It was a bad idea to expose this to them.
*/
#if USE_RVARGC
RARRAY_EMBED_LEN_MASK = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3
#else
RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
#endif
#if USE_TRANSIENT_HEAP
,
/**
* This flag has something to do with an array's "transiency". A transient
* array is an array of young generation (of generational GC), who stores
* its elements inside of dedicated memory pages called a transient heap.
* Not every young generation share that storage scheme, but elder
* generations must no join.
*
* @internal
*
* 3rd parties must not be aware that there even is more than one way to
* store array elements. It was a bad idea to expose this to them.
*/
RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13
#endif
};
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
*/
enum ruby_rarray_consts {
/** Where ::RARRAY_EMBED_LEN_MASK resides. */
RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3
#if !USE_RVARGC
,
/** Max possible number elements that can be embedded. */
RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
#endif
};
/** Ruby's array. */
struct RArray {
/** Basic part, including flags and class. */
struct RBasic basic;
/** Array's specific fields. */
union {
/**
* Arrays that use separated memory region for elements use this
* pattern.
*/
struct {
/** Number of elements of the array. */
long len;
/** Auxiliary info. */
union {
/**
* Capacity of `*ptr`. A continuous memory region of at least
* `capa` elements is expected to exist at `*ptr`. This can be
* bigger than `len`.
*/
long capa;
/**
* Parent of the array. Nowadays arrays can share their
* backend memory regions each other, constructing gigantic
* nest of objects. This situation is called "shared", and
* this is the field to control such properties.
*/
#if defined(__clang__) /* <- clang++ is sane */ || \
!defined(__cplusplus) /* <- C99 is sane */ || \
(__cplusplus > 199711L) /* <- C++11 is sane */
const
#endif
VALUE shared_root;
} aux;
/**
* Pointer to the C array that holds the elements of the array. In
* the old days each array had dedicated memory regions. That is
* no longer true today, but there still are arrays of such
* properties. This field could be used to point such things.
*/
const VALUE *ptr;
} heap;
/**
* Embedded elements. When an array is short enough, it uses this area
* to store its elements. In this case the length is encoded into the
* flags.
*/
#if USE_RVARGC
/* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
const VALUE ary[1];
#else
const VALUE ary[RARRAY_EMBED_LEN_MAX];
#endif
} as;
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* @private
*
* Declares a section of code where raw pointers are used. This is an
* implementation detail of #RARRAY_PTR_USE. People don't use it directly.
*
* @param[in] ary An object of ::RArray.
* @return `ary`'s backend C array.
*/
VALUE *rb_ary_ptr_use_start(VALUE ary);
/**
* @private
*
* Declares an end of a section formerly started by rb_ary_ptr_use_start().
* This is an implementation detail of #RARRAY_PTR_USE. People don't use it
* directly.
*
* @param[in] a An object of ::RArray.
*/
void rb_ary_ptr_use_end(VALUE a);
#if USE_TRANSIENT_HEAP
/**
* Destructively converts an array of transient backend into ordinal one.
*
* @param[out] a An object of ::RArray.
* @pre `a` must be a transient array.
* @post `a` gets out of transient heap, destructively.
*/
void rb_ary_detransient(VALUE a);
#endif
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the length of the array.
*
* @param[in] ary Array in question.
* @return Its number of elements.
* @pre `ary` must be an instance of ::RArray, and must has its
* ::RARRAY_EMBED_FLAG flag set.
*
* @internal
*
* This was a macro before. It was inevitable to be public, since macros are
* global constructs. But should it be forever? Now that it is a function,
* @shyouhei thinks it could just be eliminated, hidden into implementation
* details.
*/
static inline long
RARRAY_EMBED_LEN(VALUE ary)
{
RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));
VALUE f = RBASIC(ary)->flags;
f &= RARRAY_EMBED_LEN_MASK;
f >>= RARRAY_EMBED_LEN_SHIFT;
return RBIMPL_CAST((long)f);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* Queries the length of the array.
*
* @param[in] a Array in question.
* @return Its number of elements.
* @pre `a` must be an instance of ::RArray.
*/
static inline long
rb_array_len(VALUE a)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
return RARRAY_EMBED_LEN(a);
}
else {
return RARRAY(a)->as.heap.len;
}
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to rb_array_len(), except it differs for the return type.
*
* @param[in] ary Array in question.
* @exception rb_eRangeError Too long.
* @return Its number of elements.
* @pre `ary` must be an instance of ::RArray.
*
* @internal
*
* This API seems redundant but has actual usages.
*/
static inline int
RARRAY_LENINT(VALUE ary)
{
return rb_long2int(RARRAY_LEN(ary));
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries if the array is a transient array.
*
* @param[in] ary Array in question.
* @retval true Yes it is.
* @retval false No it isn't.
* @pre `ary` must be an instance of ::RArray.
*
* @internal
*
* @shyouhei doesn't understand the benefit of this function called from
* extension libraries.
*/
static inline bool
RARRAY_TRANSIENT_P(VALUE ary)
{
RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
#if USE_TRANSIENT_HEAP
return RB_FL_ANY_RAW(ary, RARRAY_TRANSIENT_FLAG);
#else
return false;
#endif
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* @private
*
* This is an implementation detail of RARRAY_PTR(). People do not use it
* directly.
*
* @param[in] a An object of ::RArray.
* @return Its backend storage.
*/
static inline const VALUE *
rb_array_const_ptr_transient(VALUE a)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
}
else {
return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
}
}
#if ! USE_TRANSIENT_HEAP
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
#endif
/**
* @private
*
* This is an implementation detail of RARRAY_PTR(). People do not use it
* directly.
*
* @param[in] a An object of ::RArray.
* @return Its backend storage.
* @post `a` is not a transient array.
*/
static inline const VALUE *
rb_array_const_ptr(VALUE a)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
#if USE_TRANSIENT_HEAP
if (RARRAY_TRANSIENT_P(a)) {
rb_ary_detransient(a);
}
#endif
return rb_array_const_ptr_transient(a);
}
/**
* @private
*
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*
* @param[in] a An object of ::RArray.
* @param[in] allow_transient Whether `a` can be transient or not.
* @return Its backend storage.
* @post `a` is not a transient array unless `allow_transient`.
*/
static inline VALUE *
rb_array_ptr_use_start(VALUE a,
RBIMPL_ATTR_MAYBE_UNUSED()
int allow_transient)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
#if USE_TRANSIENT_HEAP
if (!allow_transient) {
if (RARRAY_TRANSIENT_P(a)) {
rb_ary_detransient(a);
}
}
#endif
return rb_ary_ptr_use_start(a);
}
/**
* @private
*
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*
* @param[in] a An object of ::RArray.
* @param[in] allow_transient Whether `a` can be transient or not.
*/
static inline void
rb_array_ptr_use_end(VALUE a,
RBIMPL_ATTR_MAYBE_UNUSED()
int allow_transient)
{
RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);
rb_ary_ptr_use_end(a);
}
/**
* @private
*
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*/
#define RBIMPL_RARRAY_STMT(flag, ary, var, expr) do { \
RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY); \
const VALUE rbimpl_ary = (ary); \
VALUE *var = rb_array_ptr_use_start(rbimpl_ary, (flag)); \
expr; \
rb_array_ptr_use_end(rbimpl_ary, (flag)); \
} while (0)
/**
* @private
*
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*/
#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
/**
* Declares a section of code where raw pointers are used. In case you need to
* touch the raw C array instead of polite CAPIs, then that operation shall be
* wrapped using this macro.
*
* ```CXX
* const auto ary = rb_eval_string("[...]");
* const auto len = RARRAY_LENINT(ary);
* const auto symwrite = rb_intern("write");
*
* RARRAY_PTR_USE(ary, ptr, {
* rb_funcallv(rb_stdout, symwrite, len, ptr);
* });
* ```
*
* @param ary An object of ::RArray.
* @param ptr_name A variable name which points the C array in `expr`.
* @param expr The expression that touches `ptr_name`.
*
* @internal
*
* For historical reasons use of this macro is not enforced. There are
* extension libraries in the wild which call RARRAY_PTR() without it. We want
* them use it... Maybe some transition path can be implemented later.
*/
#define RARRAY_PTR_USE(ary, ptr_name, expr) \
RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
/**
* Identical to #RARRAY_PTR_USE, except the pointer can be a transient one.
*
* @param ary An object of ::RArray.
* @param ptr_name A variable name which points the C array in `expr`.
* @param expr The expression that touches `ptr_name`.
*/
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) \
RBIMPL_RARRAY_STMT(1, ary, ptr_name, expr)
/**
* Wild use of a C pointer. This function accesses the backend storage
* directly. This is slower than #RARRAY_PTR_USE_TRANSIENT. It exercises
* extra manoeuvres to protect our generational GC. Use of this function is
* considered archaic. Use a modern way instead.
*
* @param[in] ary An object of ::RArray.
* @return The backend C array.
*
* @internal
*
* That said... there are extension libraries in the wild who uses it. We
* cannot but continue supporting.
*/
static inline VALUE *
RARRAY_PTR(VALUE ary)
{
RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
}
/**
* Assigns an object in an array.
*
* @param[out] ary Destination array object.
* @param[in] i Index of `ary`.
* @param[in] v Arbitrary ruby object.
* @pre `ary` must be an instance of ::RArray.
* @pre `ary`'s length must be longer than or equal to `i`.
* @pre `i` must be greater than or equal to zero.
* @post `ary`'s `i`th element is set to `v`.
*/
static inline void
RARRAY_ASET(VALUE ary, long i, VALUE v)
{
RARRAY_PTR_USE_TRANSIENT(ary, ptr,
RB_OBJ_WRITE(ary, &ptr[i], v));
}
/**
* @deprecated
*
* :FIXME: we want to convert RARRAY_AREF into an inline function (to add rooms
* for more sanity checks). However there were situations where the address of
* this macro is taken i.e. &RARRAY_AREF(...). They cannot be possible if this
* is not a macro. Such usages are abuse, and we eliminated them internally.
* However we are afraid of similar things to remain in the wild. This macro
* remains as it is due to that. If we could warn such usages we can set a
* transition path, but currently no way is found to do so.
*/
#define RARRAY_AREF(a, i) RARRAY_CONST_PTR_TRANSIENT(a)[i]
#endif /* RBIMPL_RARRAY_H */
include/ruby/internal/core/rtypeddata.h 0000644 00000053461 15040330606 0014234 0 ustar 00 #ifndef RBIMPL_RTYPEDDATA_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RTYPEDDATA_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RTypedData.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/flag_enum.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rdata.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value_type.h"
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_TYPE_RB_DATA_TYPE_T 1
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_DATA_TYPE_T_FUNCTION 1
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_DATA_TYPE_T_PARENT 1
/**
* This is a value you can set to ::rb_data_type_struct::dfree. Setting this
* means the data was allocated using ::ruby_xmalloc() (or variants), and shall
* be freed using ::ruby_xfree().
*
* @warning Do not use this if you want to use system malloc, because the
* system and Ruby might or might not share the same malloc
* implementation.
*/
#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
/**
* This is a value you can set to ::rb_data_type_struct::dfree. Setting this
* means the data is managed by someone else, like, statically allocated. Of
* course you are on your own then.
*/
#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RTypedData.
* @return The passed object casted to ::RTypedData.
*/
#define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj))
/**
* Convenient getter macro.
*
* @param v An object, which is in fact an ::RTypedData.
* @return The passed object's ::RTypedData::data field.
*/
#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data)
/** @old{rb_check_typeddata} */
#define Check_TypedStruct(v, t) \
rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))
/** @cond INTERNAL_MACRO */
#define RTYPEDDATA_P RTYPEDDATA_P
#define RTYPEDDATA_TYPE RTYPEDDATA_TYPE
#define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
#define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED
#define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1
/** @endcond */
/**
* @private
*
* Bits for rb_data_type_struct::flags.
*/
enum
RBIMPL_ATTR_FLAG_ENUM()
rbimpl_typeddata_flags {
/**
* This flag has something to do with Ruby's global interpreter lock. For
* maximum safety, Ruby locks the entire VM during GC. However your
* callback functions could unintentionally unlock it, for instance when
* they try to flush an IO buffer. Such operations are dangerous (threads
* then run alongside of GC). By default, to prevent those scenario,
* callbacks are deferred until the GC engine is 100% sure threads can run.
* This flag skips that; structs with it are deallocated during the sweep
* phase.
*
* Using this flag needs deep understanding of both GC and threads. You
* would better leave it unspecified.
*/
RUBY_TYPED_FREE_IMMEDIATELY = 1,
/**
* This flag has something to do with Ractor. Multiple Ractors run without
* protecting each other. Sharing an object among Ractors is basically
* dangerous, disabled by default. This flag is used to bypass that
* restriction. but setting it is not enough. In addition to do so, an
* object also has to be frozen, and be passed to
* rb_ractor_make_shareable() before being actually shareable. Of course,
* you have to manually prevent race conditions then.
*
* Using this flag needs deep understanding of multithreaded programming.
* You would better leave it unspecified.
*/
RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,
/**
* This flag has something to do with our garbage collector. These days
* ruby objects are "generational". There are those who are young and
* those who are old. Young objects are prone to die; monitored relatively
* extensively by the garbage collector. OTOH old objects tend to live
* longer. They are relatively rarely considered. This basically works.
* But there is one tweak that has to be exercised. When an elder object
* has reference(s) to younger one(s), that referenced objects must not
* die. In order to detect additions of such references, old generations
* are protected by write barriers. It is a very difficult hack to
* appropriately insert write barriers everywhere. This mechanism is
* disabled by default for 3rd party extensions (they never get aged). By
* specifying this flag you can enable the generational feature to your
* data structure. Of course, you have to manually insert write barriers
* then.
*
* Using this flag needs deep understanding of GC internals, often at the
* level of source code. You would better leave it unspecified.
*/
RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */
/**
* This flag is mysterious. It seems nobody is currently using it. The
* intention of this flag is also unclear. We need further investigations.
*/
RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
};
/**
* This is the struct that holds necessary info for a struct. It roughly
* resembles a Ruby level class; multiple objects can share a ::rb_data_type_t
* instance.
*/
typedef struct rb_data_type_struct rb_data_type_t;
/** @copydoc rb_data_type_t */
struct rb_data_type_struct {
/**
* Name of structs of this kind. This is used for diagnostic purposes.
* This has to be unique in the process, but doesn't has to be a valid
* C/Ruby identifier.
*/
const char *wrap_struct_name;
/** Function pointers. Resembles C++ `vtbl`.*/
struct {
/**
* This function is called when the object is experiencing GC marks.
* If it contains references to other Ruby objects, you need to mark
* them also. Otherwise GC will smash your data.
*
* @see rb_gc_mark()
* @warning This is called during GC runs. Object allocations are
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dmark;
/**
* This function is called when the object is no longer used. You need
* to do whatever necessary to avoid memory leaks.
*
* @warning This is called during GC runs. Object allocations are
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dfree;
/**
* This function is to query the size of the underlying memory regions.
*
* @internal
*
* This function has only one usage, which is form inside of
* `ext/objspace`.
*/
size_t (*dsize)(const void *);
/**
* This function is called when the object is relocated. Like
* ::rb_data_type_struct::dmark, you need to update references to Ruby
* objects inside of your structs.
*
* @see rb_gc_location()
* @warning This is called during GC runs. Object allocations are
* impossible at that moment (that is why GC runs).
*/
RUBY_DATA_FUNC dcompact;
/**
* This field is reserved for future extension. For now, it must be
* filled with zeros.
*/
void *reserved[1]; /* For future extension.
This array *must* be filled with ZERO. */
} function;
/**
* Parent of this class. Sometimes C structs have inheritance-like
* relationships. An example is `struct sockaddr` and its family. If you
* design such things, make ::rb_data_type_t for each of them and connect
* using this field. Ruby can then transparently cast your data back and
* forth when you call #TypedData_Get_Struct().
*
* ```CXX
* struct parent { };
* static inline const rb_data_type_t parent_type = {
* .wrap_struct_name = "parent",
* };
*
* struct child: public parent { };
* static inline const rb_data_type_t child_type = {
* .wrap_struct_name = "child",
* .parent = &parent_type,
* };
*
* // This function can take both parent_class and child_class.
* static inline struct parent *
* get_parent(VALUE v)
* {
* struct parent *p;
* TypedData_Get_Struct(v, parent_type, struct parent, p);
* return p;
* }
* ```
*/
const rb_data_type_t *parent;
/**
* Type-specific static data. This area can be used for any purpose by a
* programmer who define the type. Ruby does not manage this at all.
*/
void *data; /* This area can be used for any purpose
by a programmer who define the type. */
/**
* Type-specific behavioural characteristics. This is a bitfield. It is
* an EXTREMELY WISE IDEA to leave this field blank. It is designed so
* that setting zero is the safest thing to do. If you risk to set any
* bits on, you have to know exactly what you are doing.
*
* @internal
*
* Why it has to be a ::VALUE? @shyouhei doesn't understand the design.
*/
VALUE flags; /* RUBY_FL_WB_PROTECTED */
};
/**
* "Typed" user data. By using this, extension libraries can wrap a C struct
* to make it visible from Ruby. For instance if you have a `struct timeval`,
* and you want users to use it,
*
* ```CXX
* static inline const rb_data_type_t timeval_type = {
* // Note that unspecified fields are 0-filled by default.
* .wrap_struct_name = "timeval",
* .function = {
* .dmark = nullptr, // no need to mark
* .dfree = RUBY_TYPED_DEFAULT_FREE, // use ruby_xfree()
* .dsize = [](auto) {
* return sizeof(struct timeval);
* },
* },
* };
*
* extern "C" void
* Init_timeval(void)
* {
* auto klass = rb_define_class("YourName", rb_cObject);
*
* rb_define_alloc_func(klass, [](auto klass) {
* struct timeval *t;
* auto ret = TypedData_Make_Struct(
* klass, struct timeval, &timeval_type, t);
*
* if (auto i = gettimeofday(t, nullptr); i == -1) {
* rb_sys_fail("gettimeofday(3)");
* }
* else {
* return ret;
* }
* });
* }
* ```
*/
struct RTypedData {
/** The part that all ruby objects have in common. */
struct RBasic basic;
/**
* This field stores various information about how Ruby should handle a
* data. This roughly resembles a Ruby level class (apart from method
* definition etc.)
*/
const rb_data_type_t *type;
/**
* This has to be always 1.
*
* @internal
*
* Why, then, this is not a const ::VALUE?
*/
VALUE typed_flag;
/** Pointer to the actual C level struct that you want to wrap. */
void *data;
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((3))
/**
* This is the primitive way to wrap an existing C struct into ::RTypedData.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] datap Pointer to the target C struct.
* @param[in] type The characteristics of the passed data.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return An allocated object that wraps `datap`.
*/
VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type);
/**
* Identical to rb_data_typed_object_wrap(), except it allocates a new data
* region internally instead of taking an existing one. The allocation is done
* using ruby_calloc(). Hence it makes no sense for `type->function.dfree` to
* be anything other than ::RUBY_TYPED_DEFAULT_FREE.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] size Requested size of memory to allocate.
* @param[in] type The characteristics of the passed data.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return An allocated object that wraps a new `size` byte region.
*/
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);
/**
* Checks for the domestic relationship between the two.
*
* @param[in] child A data type supposed to be a child of `parent`.
* @param[in] parent A data type supposed to be a parent of `child`.
* @retval true `child` is a descendent of `parent`.
* @retval false Otherwise.
*
* @internal
*
* You can path NULL to both arguments, don't know what that means though.
*/
int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);
/**
* Checks if the given object is of given kind.
*
* @param[in] obj An instance of ::RTypedData.
* @param[in] data_type Expected data type of `obj`.
* @retval true `obj` is of `data_type`.
* @retval false Otherwise.
*/
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);
/**
* Identical to rb_typeddata_is_kind_of(), except it raises exceptions instead
* of returning false.
*
* @param[in] obj An instance of ::RTypedData.
* @param[in] data_type Expected data type of `obj`.
* @exception rb_eTypeError obj is not of `data_type`.
* @return Unwrapped C struct that `obj` holds.
* @post Upon successful return `obj`'s type is guaranteed `data_type`.
*/
void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
RBIMPL_SYMBOL_EXPORT_END()
/**
* Converts sval, a pointer to your struct, into a Ruby object.
*
* @param klass A ruby level class.
* @param data_type The type of `sval`.
* @param sval A pointer to your struct.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
*/
#define TypedData_Wrap_Struct(klass,data_type,sval)\
rb_data_typed_object_wrap((klass),(sval),(data_type))
/**
* @private
*
* This is an implementation detail of #TypedData_Make_Struct. People don't
* use it directly.
*
* @param result Variable name of created Ruby object.
* @param klass Ruby level class of the object.
* @param type Type name of the C struct.
* @param size Size of the C struct.
* @param data_type The data type describing `type`.
* @param sval Variable name of created C struct.
*/
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
VALUE result = rb_data_typed_object_zalloc(klass, size, data_type); \
(sval) = RBIMPL_CAST((type *)RTYPEDDATA_DATA(result)); \
RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))
/**
* Identical to #TypedData_Wrap_Struct, except it allocates a new data region
* internally instead of taking an existing one. The allocation is done using
* ruby_calloc(). Hence it makes no sense for `data_type->function.dfree` to
* be anything other than ::RUBY_TYPED_DEFAULT_FREE.
*
* @param klass Ruby level class of the object.
* @param type Type name of the C struct.
* @param data_type The data type describing `type`.
* @param sval Variable name of created C struct.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
*/
#ifdef HAVE_STMT_AND_DECL_IN_EXPR
#define TypedData_Make_Struct(klass, type, data_type, sval) \
RB_GNUC_EXTENSION({ \
TypedData_Make_Struct0( \
data_struct_obj, \
klass, \
type, \
sizeof(type), \
data_type, \
sval); \
data_struct_obj; \
})
#else
#define TypedData_Make_Struct(klass, type, data_type, sval) \
rb_data_typed_object_make( \
(klass), \
(data_type), \
RBIMPL_CAST((void **)&(sval)), \
sizeof(type))
#endif
/**
* Obtains a C struct from inside of a wrapper Ruby object.
*
* @param obj An instance of ::RTypedData.
* @param type Type name of the C struct.
* @param data_type The data type describing `type`.
* @param sval Variable name of obtained C struct.
* @exception rb_eTypeError `obj` is not a kind of `data_type`.
* @return Unwrapped C struct that `obj` holds.
*/
#define TypedData_Get_Struct(obj,type,data_type,sval) \
((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))
RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
* This is an implementation detail of Check_Type(). People don't use it
* directly.
*
* @param[in] obj Object in question
* @retval true `obj` is an instance of ::RTypedData.
* @retval false `obj` is an instance of ::RData.
* @pre `obj` must be a Ruby object of ::RUBY_T_DATA.
*/
static inline bool
rbimpl_rtypeddata_p(VALUE obj)
{
return RTYPEDDATA(obj)->typed_flag == 1;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks whether the passed object is ::RTypedData or ::RData.
*
* @param[in] obj Object in question
* @retval true `obj` is an instance of ::RTypedData.
* @retval false `obj` is an instance of ::RData.
* @pre `obj` must be a Ruby object of ::RUBY_T_DATA.
*/
static inline bool
RTYPEDDATA_P(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
Check_Type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(false);
}
#endif
return rbimpl_rtypeddata_p(obj);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
* Queries for the type of given object.
*
* @param[in] obj Object in question
* @return Data type struct that corresponds to `obj`.
* @pre `obj` must be an instance of ::RTypedData.
*/
static inline const struct rb_data_type_struct *
RTYPEDDATA_TYPE(VALUE obj)
{
#if RUBY_DEBUG
if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
rb_unexpected_type(obj, RUBY_T_DATA);
RBIMPL_UNREACHABLE_RETURN(NULL);
}
#endif
return RTYPEDDATA(obj)->type;
}
/**
* While we don't stop you from using this function, it seems to be an
* implementation detail of #TypedData_Make_Struct, which is preferred over
* this one.
*
* @param[in] klass Ruby level class of the returning object.
* @param[in] type The data type
* @param[out] datap Return pointer.
* @param[in] size Size of the C struct.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eNoMemError Out of memory.
* @return A created Ruby object.
* @post `*datap` points to the C struct wrapped by the returned object.
*/
static inline VALUE
rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
{
TypedData_Make_Struct0(result, klass, void, size, type, *datap);
return result;
}
RBIMPL_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
/** @deprecated This function was renamed to rb_data_typed_object_wrap(). */
static inline VALUE
rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
{
return rb_data_typed_object_wrap(klass, datap, type);
}
#endif /* RBIMPL_RTYPEDDATA_H */
include/ruby/internal/core/rfile.h 0000644 00000004132 15040330606 0013163 0 ustar 00 #ifndef RBIMPL_RFILE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RFILE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines struct ::RFile.
*/
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/cast.h"
/* rb_io_t is in ruby/io.h. The header file has historically not been included
* into ruby/ruby.h. We follow that tradition. */
struct rb_io_t;
/**
* Ruby's File and IO. Ruby's IO are not just file descriptors. They have
* buffers. They also have encodings. Various information are controlled
* using this struct.
*/
struct RFile {
/** Basic part, including flags and class. */
struct RBasic basic;
/** IO's specific fields. */
struct rb_io_t *fptr;
};
/**
* Convenient casting macro.
*
* @param obj An object, which is in fact an ::RFile.
* @return The passed object casted to ::RFile.
*/
#define RFILE(obj) RBIMPL_CAST((struct RFile *)(obj))
#endif /* RBIMPL_RFILE_H */
include/ruby/internal/symbol.h 0000644 00000031432 15040330606 0012442 0 ustar 00 #ifndef RBIMPL_SYMBOL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SYMBOL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #rb_intern
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/value.h"
#define RB_ID2SYM rb_id2sym /**< @alias{rb_id2sym} */
#define RB_SYM2ID rb_sym2id /**< @alias{rb_sym2id} */
#define ID2SYM RB_ID2SYM /**< @old{RB_ID2SYM} */
#define SYM2ID RB_SYM2ID /**< @old{RB_SYM2ID} */
#define CONST_ID_CACHE RUBY_CONST_ID_CACHE /**< @old{RUBY_CONST_ID_CACHE} */
#define CONST_ID RUBY_CONST_ID /**< @old{RUBY_CONST_ID} */
/** @cond INTERNAL_MACRO */
#define rb_intern_const rb_intern_const
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Converts an instance of ::rb_cSymbol into an ::ID.
*
* @param[in] obj An instance of ::rb_cSymbol.
* @exception rb_eTypeError `obj` is not an instance of ::rb_cSymbol.
* @return An ::ID of the identical symbol.
*/
ID rb_sym2id(VALUE obj);
/**
* Allocates an instance of ::rb_cSymbol that has the given id.
*
* @param[in] id An id.
* @retval RUBY_Qfalse No such id ever existed in the history.
* @retval Otherwise An allocated ::rb_cSymbol instance.
*/
VALUE rb_id2sym(ID id);
RBIMPL_ATTR_NONNULL(())
/**
* Finds or creates a symbol of the given name.
*
* @param[in] name The name of the id.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given name.
* @note These days Ruby internally has two kinds of symbols (static /
* dynamic). Symbols created using this function would become a
* static one; i.e. would never be garbage collected. It is up to
* you to avoid memory leaks. Think twice before using it.
*/
ID rb_intern(const char *name);
/**
* Identical to rb_intern(), except it additionally takes the length of the
* string. This way you can have a symbol that contains NUL characters.
*
* @param[in] name The name of the id.
* @param[in] len Length of `name`.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given name.
* @note These days Ruby internally has two kinds of symbols
* (static/dynamic). Symbols created using this function would
* become static ones; i.e. would never be garbage collected. It
* is up to you to avoid memory leaks. Think twice before using
* it.
*/
ID rb_intern2(const char *name, long len);
/**
* Identical to rb_intern(), except it takes an instance of ::rb_cString.
*
* @param[in] str The name of the id.
* @pre `str` must either be an instance of ::rb_cSymbol, or an instance
* of ::rb_cString, or responds to `#to_str` method.
* @exception rb_eTypeError Can't convert `str` into ::rb_cString.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given str.
* @note These days Ruby internally has two kinds of symbols
* (static/dynamic). Symbols created using this function would
* become static ones; i.e. would never be garbage collected. It
* is up to you to avoid memory leaks. Think twice before using
* it.
*/
ID rb_intern_str(VALUE str);
/**
* Retrieves the name mapped to the given id.
*
* @param[in] id An id to query.
* @retval NULL No such id ever existed in the history.
* @retval otherwise A name that the id represents.
* @note The return value is managed by the interpreter. Don't pass it
* to free().
*/
const char *rb_id2name(ID id);
RBIMPL_ATTR_NONNULL(())
/**
* Detects if the given name is already interned or not. It first tries to
* convert the argument to an instance of ::rb_cString if it is neither an
* instance of ::rb_cString nor ::rb_cSymbol. The conversion result is written
* back to the variable. Then queries if that name was already interned
* before. If found it returns such id, otherwise zero.
*
* We eventually introduced this API to avoid inadvertent symbol pin-down.
* Before, there was no way to know if an ID was already interned or not
* without actually creating one (== leaking memory). By using this API you
* can avoid such situations:
*
* ```CXX
* bool does_interning_this_leak_memory(VALUE obj)
* {
* auto tmp = obj;
* if (auto id = rb_check_id(&tmp); id) {
* return false;
* }
* else {
* return true; // Let GC sweep tmp if necessary.
* }
* }
* ```
*
* @param[in,out] namep A pointer to a name to query.
* @pre The object referred by `*namep` must either be an instance
* of ::rb_cSymbol, or an instance of ::rb_cString, or responds
* to `#to_str` method.
* @exception rb_eTypeError Can't convert `*namep` into ::rb_cString.
* @exception rb_eEncodingError Given string is non-ASCII.
* @retval 0 No such id ever existed in the history.
* @retval otherwise The id that represents the given name.
* @post The object that `*namep` points to is a converted result
* object, which is always an instance of either ::rb_cSymbol
* or ::rb_cString.
* @see https://bugs.ruby-lang.org/issues/5072
*
* @internal
*
* @shyouhei doesn't know why this has to raise rb_eEncodingError.
*/
ID rb_check_id(volatile VALUE *namep);
/**
* @copydoc rb_intern_str()
*
* @internal
*
* :FIXME: Can anyone tell us what is the difference between this one and
* rb_intern_str()? As far as @shyouhei reads the implementation it seems what
* rb_to_id() does is is just waste some CPU time, then call rb_intern_str().
* He hopes he is wrong.
*/
ID rb_to_id(VALUE str);
/**
* Identical to rb_id2name(), except it returns a Ruby's String instead of C's.
*
* @param[in] id An id to query.
* @retval RUBY_Qfalse No such id ever existed in the history.
* @retval otherwise An instance of ::rb_cString with the name of id.
*
* @internal
*
* In reality "rb_id2str() is identical to rb_id2name() except it returns Ruby
* string" is just describing things upside down; truth is `rb_id2name(foo)` is
* a shorthand of `RSTRING_PTR(rb_id2str(foo))`.
*/
VALUE rb_id2str(ID id);
/**
* Identical to rb_id2str(), except it takes an instance of ::rb_cSymbol rather
* than an ::ID.
*
* @param[in] id An id to query.
* @retval RUBY_Qfalse No such id ever existed in the history.
* @retval otherwise An instance of ::rb_cString with the name of id.
*/
VALUE rb_sym2str(VALUE id);
/**
* Identical to rb_intern_str(), except it generates a dynamic symbol if
* necessary.
*
* @param[in] name The name of the id.
* @pre `name` must either be an instance of ::rb_cSymbol, or an
* instance of ::rb_cString, or responds to `#to_str` method.
* @exception rb_eTypeError Can't convert `name` into ::rb_cString.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given name.
* @note These days Ruby internally has two kinds of symbols
* (static/dynamic). Symbols created using this function would
* become dynamic ones; i.e. would be garbage collected. It could
* be safer for you to use it than alternatives, when applicable.
*/
VALUE rb_to_symbol(VALUE name);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_check_id(), except it returns an instance of ::rb_cSymbol
* instead.
*
* @param[in,out] namep A pointer to a name to query.
* @pre The object referred by `*namep` must either be an instance
* of ::rb_cSymbol, or an instance of ::rb_cString, or responds
* to `#to_str` method.
* @exception rb_eTypeError Can't convert `*namep` into ::rb_cString.
* @exception rb_eEncodingError Given string is non-ASCII.
* @retval RUBY_Qnil No such id ever existed in the history.
* @retval otherwise The id that represents the given name.
* @post The object that `*namep` points to is a converted result
* object, which is always an instance of either ::rb_cSymbol
* or ::rb_cString.
* @see https://bugs.ruby-lang.org/issues/5072
*
* @internal
*
* @shyouhei doesn't know why this has to raise rb_eEncodingError.
*/
VALUE rb_check_symbol(volatile VALUE *namep);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE()
RBIMPL_ATTR_NONNULL(())
/**
* This is a "tiny optimisation" over rb_intern(). If you pass a string
* _literal_, and if your C compiler can special-case strlen of such literal to
* strength-reduce into an integer constant expression, then this inline
* function can precalc a part of conversion.
*
* @note This function also works happily for non-constant strings. Why
* bother then? Just apply liberally to everything.
* @note But #rb_intern() could be faster on compilers with statement
* expressions, because they can cache the created ::ID.
* @param[in] str The name of the id.
* @exception rb_eRuntimeError Too many symbols.
* @return A (possibly new) id whose value is the given str.
* @note These days Ruby internally has two kinds of symbols (static /
* dynamic). Symbols created using this function would become a
* static one; i.e. would never be garbage collected. It is up to
* you to avoid memory leaks. Think twice before using it.
*/
static inline ID
rb_intern_const(const char *str)
{
size_t len = strlen(str);
return rb_intern2(str, RBIMPL_CAST((long)len));
}
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail of #rb_intern(). Just don't use it.
*/
static inline ID
rbimpl_intern_const(ID *ptr, const char *str)
{
while (! *ptr) {
*ptr = rb_intern_const(str);
}
return *ptr;
}
/**
* Old implementation detail of rb_intern().
* @deprecated Does anyone use it? Preserved for backward compat.
*/
#define RUBY_CONST_ID_CACHE(result, str) \
{ \
static ID rb_intern_id_cache; \
rbimpl_intern_const(&rb_intern_id_cache, (str)); \
result rb_intern_id_cache; \
}
/**
* Old implementation detail of rb_intern().
* @deprecated Does anyone use it? Preserved for backward compat.
*/
#define RUBY_CONST_ID(var, str) \
do { \
static ID rbimpl_id; \
(var) = rbimpl_intern_const(&rbimpl_id, (str)); \
} while (0)
#if defined(HAVE_STMT_AND_DECL_IN_EXPR)
/* __builtin_constant_p and statement expression is available
* since gcc-2.7.2.3 at least. */
#define rb_intern(str) \
(RBIMPL_CONSTANT_P(str) ? \
__extension__ ({ \
static ID rbimpl_id; \
rbimpl_intern_const(&rbimpl_id, (str)); \
}) : \
(rb_intern)(str))
#endif
#endif /* RBIMPL_SYMBOL_H */
include/ruby/internal/assume.h 0000644 00000006255 15040330606 0012437 0 ustar 00 #ifndef RBIMPL_ASSUME_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ASSUME_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ASSUME / #RBIMPL_UNREACHABLE.
*
* These macros must be defined at once because:
*
* - #RBIMPL_ASSUME could fallback to #RBIMPL_UNREACHABLE.
* - #RBIMPL_UNREACHABLE could fallback to #RBIMPL_ASSUME.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/warning_push.h"
/** @cond INTERNAL_MACRO */
#if defined(HAVE___ASSUME)
# define RBIMPL_HAVE___ASSUME
#endif
/** @endcond */
/** Wraps (or simulates) `__builtin_unreachable`. */
#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
# define RBIMPL_UNREACHABLE_RETURN(_) __builtin_unreachable()
#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_UNREACHABLE_RETURN(_) return (__assume(0), (_))
#else
# define RBIMPL_UNREACHABLE_RETURN(_) return (_)
#endif
/** Wraps (or simulates) `__builtin_unreachable`. */
#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
# define RBIMPL_UNREACHABLE __builtin_unreachable
#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_UNREACHABLE() __assume(0)
#endif
/** Wraps (or simulates) `__assume`. */
#if RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# /* icc warnings are false positives. Ignore them. */
# /* "warning #2261: __assume expression with side effects discarded" */
# define RBIMPL_ASSUME(expr) \
RBIMPL_WARNING_PUSH() \
RBIMPL_WARNING_IGNORED(2261) \
__assume(expr) \
RBIMPL_WARNING_POP()
#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_ASSUME __assume
#elif RBIMPL_HAS_BUILTIN(__builtin_assume)
# define RBIMPL_ASSUME __builtin_assume
#elif ! defined(RBIMPL_UNREACHABLE)
# define RBIMPL_ASSUME(_) RBIMPL_CAST((void)(_))
#else
# define RBIMPL_ASSUME(_) \
(RB_LIKELY(!!(_)) ? RBIMPL_CAST((void)0) : RBIMPL_UNREACHABLE())
#endif
#if ! defined(RBIMPL_UNREACHABLE)
# define RBIMPL_UNREACHABLE() RBIMPL_ASSUME(0)
#endif
#endif /* RBIMPL_ASSUME_H */
include/ruby/internal/interpreter.h 0000644 00000022723 15040330606 0013503 0 ustar 00 #ifndef RBIMPL_INTERPRETER_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERPRETER_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Interpreter embedding APIs.
*/
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* @defgroup embed CRuby Embedding APIs
*
* CRuby interpreter APIs. These are APIs to embed MRI interpreter into your
* program.
* These functions are not a part of Ruby extension library API.
* Extension libraries of Ruby should not depend on these functions.
*
* @{
*/
/**
* @defgroup ruby1 ruby(1) implementation
*
* A part of the implementation of ruby(1) command.
* Other programs that embed Ruby interpreter do not always need to use these
* functions.
*
* @{
*/
RBIMPL_ATTR_NONNULL(())
/**
* Initializes the process for libruby.
*
* This function assumes this process is `ruby(1)` and it has just started.
* Usually programs that embed CRuby interpreter may not call this function,
* and may do their own initialization.
*
* @param[in] argc Pointer to process main's `argc`.
* @param[in] argv Pointer to process main's `argv`.
* @warning `argc` and `argv` cannot be `NULL`.
*
* @internal
*
* AFAIK Ruby does write to argv, especially `argv[0][0]`, via setproctitle(3).
* It is intentional that the argument is not const-qualified.
*/
void ruby_sysinit(int *argc, char ***argv);
/**
* Calls ruby_setup() and check error.
*
* Prints errors and calls exit(3) if an error occurred.
*/
void ruby_init(void);
/**
* Processes command line arguments and compiles the Ruby source to execute.
*
* This function does:
* - Processes the given command line flags and arguments for `ruby(1)`
* - Compiles the source code from the given argument, `-e` or `stdin`, and
* - Returns the compiled source as an opaque pointer to an internal data
* structure
*
* @param[in] argc Process main's `argc`.
* @param[in] argv Process main's `argv`.
* @return An opaque pointer to the compiled source or an internal special
* value. Pass it to ruby_executable_node() to detect which.
* @see ruby_executable_node
*/
void* ruby_options(int argc, char** argv);
/**
* Checks the return value of ruby_options().
*
* ruby_options() sometimes returns a special value to indicate this process
* should immediately exit. This function checks if the case. Also stores the
* exit status that the caller have to pass to exit(3) into `*status`.
*
* @param[in] n A return value of ruby_options().
* @param[out] status Pointer to the exit status of this process.
* @retval 0 The given value is such a special value.
* @retval otherwise The given opaque pointer is actually a compiled
* source.
*/
int ruby_executable_node(void *n, int *status);
/**
* Runs the given compiled source and exits this process.
*
* @param[in] n Opaque "node" pointer.
* @retval EXIT_SUCCESS Successfully run the source.
* @retval EXIT_FAILURE An error occurred.
*/
int ruby_run_node(void *n);
/* version.c */
/** Prints the version information of the CRuby interpreter to stdout. */
void ruby_show_version(void);
#ifndef ruby_show_copyright
/** Prints the copyright notice of the CRuby interpreter to stdout. */
void ruby_show_copyright(void);
#endif
/**
* A convenience macro to call ruby_init_stack().
* Must be placed just after variable declarations.
*/
#define RUBY_INIT_STACK \
VALUE variable_in_this_stack_frame; \
ruby_init_stack(&variable_in_this_stack_frame);
/** @} */
/**
* Set stack bottom of Ruby implementation.
*
* You must call this function before any heap allocation by Ruby
* implementation. Or GC will break living objects.
*
* @param[in] addr A pointer somewhere on the stack, near its bottom.
*/
void ruby_init_stack(volatile VALUE *addr);
/**
* Initializes the VM and builtin libraries.
*
* @retval 0 Initialization succeeded.
* @retval otherwise An error occurred.
*
* @internal
*
* Though not a part of our public API, the return value is in fact an enum
* ruby_tag_type. You can see the potential "otherwise" values by looking at
* vm_core.h.
*/
int ruby_setup(void);
/**
* Destructs the VM.
*
* Runs the VM finalization processes as well as ruby_finalize(), and frees
* resources used by the VM.
*
* @param[in] ex Default value to the return value.
* @retval EXIT_FAILURE An error occurred.
* @retval ex Successful cleanup.
* @note This function does not raise any exception.
*/
int ruby_cleanup(int ex);
/**
* Runs the VM finalization processes.
*
* `END{}` and procs registered by `Kernel.#at_exit` are executed here. See the
* Ruby language spec for more details.
*
* @note This function is allowed to raise an exception if an error occurred.
*/
void ruby_finalize(void);
RBIMPL_ATTR_NORETURN()
/** Calls ruby_cleanup() and exits the process. */
void ruby_stop(int);
/**
* Checks for stack overflow.
*
* @retval true NG machine stack is about to overflow.
* @retval false OK there still is a room in the stack.
*
* @internal
*
* Does anybody use it? So far @shyouhei have never seen any actual use-case.
*/
int ruby_stack_check(void);
/**
* Queries what Ruby thinks is the machine stack. Ruby manages a region of
* memory. It calls that area the "machine stack". By calling this function,
* in spite of its name, you can obtain both one end of the stack and its
* length at once. Which means you can know the entire region.
*
* @param[out] topnotch On return the pointer points to the upmost address of
* the macihne stack that Ruby knows.
* @return Length of the machine stack that Ruby knows.
*
* @internal
*
* Does anybody use it? @shyouhei is quite skeptical if this is useful outside
* of the VM. Maybe it was a wrong idea to expose this API to 3rd parties.
*/
size_t ruby_stack_length(VALUE **topnotch);
/**
* Identical to ruby_run_node(), except it returns an opaque execution status.
* You can pass it to rb_cleanup().
*
* @param[in] n Opaque "node" pointer.
* @retval 0 Successful end-of-execution.
* @retval otherwise An error occurred.
*
* @internal
*
* Though not a part of our public API, the return value is in fact an enum
* ruby_tag_type. You can see the potential "otherwise" values by looking at
* vm_core.h.
*/
int ruby_exec_node(void *n);
/**
* Sets the current script name to this value.
*
* This is similar to `$0 = name` in Ruby level but also affects
* `Method#location` and others.
*
* @param[in] name File name to set.
*/
void ruby_script(const char* name);
/**
* Identical to ruby_script(), except it takes the name as a Ruby String
* instance.
*
* @param[in] name File name to set.
*/
void ruby_set_script_name(VALUE name);
/** Defines built-in variables */
void ruby_prog_init(void);
/**
* Sets argv that ruby understands. Your program might have its own command
* line parameters etc. Handle them as you wish, and pass remaining parts of
* argv here.
*
* @param[in] argc Number of elements of `argv`.
* @param[in] argv Command line arguments.
*/
void ruby_set_argv(int argc, char **argv);
/**
* Identical to ruby_options(), except it raises ruby-level exceptions on
* failure.
*
* @param[in] argc Process main's `argc`.
* @param[in] argv Process main's `argv`.
* @return An opaque "node" pointer.
*/
void *ruby_process_options(int argc, char **argv);
/**
* Sets up `$LOAD_PATH`.
*
* @internal
*
* @shyouhei guesses this has to be called at very later stage, at least after
* the birth of object system. But is not exactly sure when.
*/
void ruby_init_loadpath(void);
/**
* Appends the given path to the end of the load path.
*
* @pre ruby_init_loadpath() must be done beforehand.
* @param[in] path The path you want to push to the load path.
*/
void ruby_incpush(const char *path);
/**
* Clear signal handlers.
*
* Ruby installs its own signal handler (apart from those which user scripts
* set). This is to clear that. Must be called when the ruby part terminates,
* before switching to your program's own logic.
*/
void ruby_sig_finalize(void);
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERPRETER_H */
include/ruby/internal/memory.h 0000644 00000056052 15040330606 0012452 0 ustar 00 #ifndef RBIMPL_MEMORY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_MEMORY_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Memory management stuff.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#if defined(_MSC_VER) && defined(_WIN64)
# include <intrin.h>
# pragma intrinsic(_umul128)
#endif
#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/stdalign.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/xmalloc.h"
#include "ruby/backward/2/limits.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/assume.h"
#include "ruby/defines.h"
/** @cond INTENAL_MACRO */
/* Make alloca work the best possible way. */
#if defined(alloca)
# /* Take that. */
#elif RBIMPL_HAS_BUILTIN(__builtin_alloca)
# define alloca __builtin_alloca
#elif defined(_AIX)
# pragma alloca
#elif defined(__cplusplus)
extern "C" void *alloca(size_t);
#else
extern void *alloca();
#endif
/** @endcond */
#if defined(__DOXYGEN__)
/**
* @private
*
* Type that is as twice wider as size_t. This is an implementation detail of
* rb_mul_size_overflow(). People should not use it. This is not a good name
* either.
*/
typedef uint128_t DSIZE_T;
#elif defined(HAVE_INT128_T) && SIZEOF_SIZE_T <= 8
# define DSIZE_T uint128_t
#elif SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG
# define DSIZE_T unsigned LONG_LONG
#endif
/**
* @private
*
* Maximum possible number of bytes that #RB_ALLOCV can allocate using
* `alloca`. Anything beyond this is allocated using rb_alloc_tmp_buffer().
* This selection is transparent to users. People don't have to bother.
*/
#ifdef C_ALLOCA
# define RUBY_ALLOCV_LIMIT 0
#else
# define RUBY_ALLOCV_LIMIT 1024
#endif
/**
* Prevents premature destruction of local objects. Ruby's garbage collector
* is conservative; it scans the C level machine stack as well. Possible in-
* use Ruby objects must remain visible on stack, to be properly marked as
* such. However contemporary C compilers do not interface well with this.
* Consider the following example:
*
* ```CXX
* auto s = rb_str_new_cstr(" world");
* auto sptr = RSTRING_PTR(s);
* auto t = rb_str_new_cstr("hello,"); // Possible GC invocation
* auto u = rb_str_cat_cstr(t, sptr);
*
* RB_GC_GUARD(s); // ensure `s` (and thus `sptr`) do not get GC-ed
* ```
*
* Here, without the #RB_GC_GUARD, the last use of `s` is _before_ the last use
* of `sptr`. Compilers could thus think `s` and `t` are allowed to overlap.
* That would eliminate `s` from the stack, while `sptr` is still in use. If
* our GC ran at that very moment, `s` gets swept out, which also destroys
* `sptr`. Boom! You got a SEGV.
*
* In order to prevent this scenario #RB_GC_GUARD must be placed _after_ the
* last use of `sptr`. Placing #RB_GC_GUARD before dereferencing `sptr` would
* be of no use.
*
* #RB_GC_GUARD would not be necessary at all in the above example if non-
* inlined function calls are made on the `s` variable after `sptr` is
* dereferenced. Thus, in the above example, calling any un-inlined function
* on `s` such as `rb_str_modify(s);` will ensure `s` stays on the stack or
* register to prevent a GC invocation from prematurely freeing it.
*
* Using the #RB_GC_GUARD macro is preferable to using the `volatile` keyword
* in C. #RB_GC_GUARD has the following advantages:
*
* - the intent of the macro use is clear.
*
* - #RB_GC_GUARD only affects its call site. OTOH `volatile` generates some
* extra code every time the variable is used, hurting optimisation.
*
* - `volatile` implementations may be buggy/inconsistent in some compilers
* and architectures. #RB_GC_GUARD is customisable for broken
* systems/compilers without negatively affecting other systems.
*
* - C++ since C++20 deprecates `volatile`. If you write your extension
* library in that language there is no escape but to use this macro.
*
* @param v A variable of ::VALUE type.
* @post `v` is still alive.
*/
#ifdef __GNUC__
#define RB_GC_GUARD(v) \
(*__extension__ ({ \
volatile VALUE *rb_gc_guarded_ptr = &(v); \
__asm__("" : : "m"(rb_gc_guarded_ptr)); \
rb_gc_guarded_ptr; \
}))
#elif defined _MSC_VER
#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr(&(v)))
#else
#define HAVE_RB_GC_GUARDED_PTR_VAL 1
#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr_val(&(v),(v)))
#endif
/* Casts needed because void* is NOT compatible with others in C++. */
/**
* Convenient macro that allocates an array of n elements.
*
* @param type Type of array elements.
* @param n Length of the array.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError Integer overflow trying to calculate the length
* of continuous memory region of `n` elements of
* `type`.
* @return Storage instance that is capable of storing at least `n`
* elements of type `type`.
* @note It doesn't return NULL, even when `n` is zero.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
#define RB_ALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))
/**
* Shorthand of #RB_ALLOC_N with `n=1`.
*
* @param type Type of allocation.
* @exception rb_eNoMemError No space left for allocation.
* @return Storage instance that can hold an `type` object.
* @note It doesn't return NULL.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
#define RB_ALLOC(type) RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))
/**
* Identical to #RB_ALLOC_N() but also nullifies the allocated region before
* returning.
*
* @param type Type of array elements.
* @param n Length of the array.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError Integer overflow trying to calculate the length
* of continuous memory region of `n` elements of
* `type`.
* @return Storage instance that is capable of storing at least `n`
* elements of type `type`.
* @post Returned array is filled with zeros.
* @note It doesn't return NULL, even when `n` is zero.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
#define RB_ZALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))
/**
* Shorthand of #RB_ZALLOC_N with `n=1`.
*
* @param type Type of allocation.
* @exception rb_eNoMemError No space left for allocation.
* @return Storage instance that can hold an `type` object.
* @post Returned object is filled with zeros.
* @note It doesn't return NULL.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
#define RB_ZALLOC(type) (RB_ZALLOC_N(type, 1))
/**
* Convenient macro that reallocates an array with a new size.
*
* @param var A variable of `type`, which points to a storage
* instance that was previously returned from
* either
* - ruby_xmalloc(),
* - ruby_xmalloc2(),
* - ruby_xcalloc(),
* - ruby_xrealloc(), or
* - ruby_xrealloc2().
* @param type Type of allocation.
* @param n Requested new size of each element.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError Integer overflow trying to calculate the length
* of continuous memory region of `n` elements of
* `type`.
* @return Storage instance that is capable of storing at least `n`
* elements of type `type`.
* @pre The passed variable must point to a valid live storage instance.
* It is a failure to pass a variable that holds an already-freed
* pointer.
* @note It doesn't return NULL, even when `n` is zero.
* @warning Do not assume anything on the alignment of the return value.
* There is no guarantee that it inherits the passed argument's
* one.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
#define RB_REALLOC_N(var,type,n) \
((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))
/**
* @deprecated This macro is dangerous (does not bother stack overflow at
* all). #RB_ALLOCV is the modern way to do the same thing.
* @param type Type of array elements.
* @param n Length of the array.
* @return A pointer on stack.
*/
#define ALLOCA_N(type,n) \
RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))
/**
* Identical to #RB_ALLOCV_N(), except that it allocates a number of bytes and
* returns a void* .
*
* @param v A variable to hold the just-in-case opaque Ruby object.
* @param n Size of allocation, in bytes.
* @return A void pointer to `n` bytes storage.
* @note `n` may be evaluated twice.
*/
#define RB_ALLOCV(v, n) \
((n) < RUBY_ALLOCV_LIMIT ? \
((v) = 0, alloca(n)) : \
rb_alloc_tmp_buffer(&(v), (n)))
/**
* Allocates a memory region, possibly on stack. If the given size exceeds
* #RUBY_ALLOCV_LIMIT, it allocates a dedicated opaque ruby object instead and
* let our GC sweep that region after use. Either way you can fire-and-forget.
*
* ```CXX
* #include <sys/types.h>
*
* VALUE
* foo(int n)
* {
* VALUE v;
* auto ptr = RB_ALLOCV(struct tms, v, n);
* ...
* // no need to free `ptr`.
* }
* ```
*
* If you want to be super-duper polite you can also explicitly state the end
* of use of such memory region by calling #RB_ALLOCV_END().
*
* @param type The type of array elements.
* @param v A variable to hold the just-in-case opaque Ruby object.
* @param n Number of elements requested to allocate.
* @return An array of `n` elements of `type`.
* @note `n` may be evaluated twice.
*/
#define RB_ALLOCV_N(type, v, n) \
RBIMPL_CAST((type *) \
(((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \
((v) = 0, alloca((n) * sizeof(type))) : \
rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))))
/**
* Polite way to declare that the given array is not used any longer. Calling
* this not mandatory. Our GC can baby-sit you. However it is not a very bad
* idea to use it when possible. Doing so could reduce memory footprint.
*
* @param v A variable previously passed to either #RB_ALLOCV/#RB_ALLOCV_N.
*/
#define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v))
/**
* Handy macro to erase a region of memory.
*
* @param p Target pointer.
* @param type Type of `p[0]`
* @param n Length of `p`.
* @return `p`.
* @post First `n` elements of `p` are squashed.
*/
#define MEMZERO(p,type,n) memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))
/**
* Handy macro to call memcpy.
*
* @param p1 Destination pointer.
* @param p2 Source pointer.
* @param type Type of `p2[0]`
* @param n Length of `p2`.
* @return `p1`.
* @post First `n` elements of `p2` are copied into `p1`.
*/
#define MEMCPY(p1,p2,type,n) ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
/**
* Handy macro to call memmove.
*
* @param p1 Destination pointer.
* @param p2 Source pointer.
* @param type Type of `p2[0]`
* @param n Length of `p2`.
* @return `p1`.
* @post First `n` elements of `p2` are copied into `p1`.
*/
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
/**
* Handy macro to call memcmp
*
* @param p1 Target LHS.
* @param p2 Target RHS.
* @param type Type of `p1[0]`
* @param n Length of `p1`.
* @retval <0 `p1` is "less" than `p2`.
* @retval 0 `p1` is equal to `p2`.
* @retval >0 `p1` is "greater" than `p2`.
*/
#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
#define ALLOC_N RB_ALLOC_N /**< @old{RB_ALLOC_N} */
#define ALLOC RB_ALLOC /**< @old{RB_ALLOC} */
#define ZALLOC_N RB_ZALLOC_N /**< @old{RB_ZALLOC_N} */
#define ZALLOC RB_ZALLOC /**< @old{RB_ZALLOC} */
#define REALLOC_N RB_REALLOC_N /**< @old{RB_REALLOC_N} */
#define ALLOCV RB_ALLOCV /**< @old{RB_ALLOCV} */
#define ALLOCV_N RB_ALLOCV_N /**< @old{RB_ALLOCV_N} */
#define ALLOCV_END RB_ALLOCV_END /**< @old{RB_ALLOCV_END} */
/**
* @private
*
* This is an implementation detail of rbimpl_size_mul_overflow().
*
* @internal
*
* Expecting this struct to be eliminated by function inlinings. This is
* nothing more than std::variant<std::size_t> if we could use recent C++, but
* reality is we cannot.
*/
struct rbimpl_size_mul_overflow_tag {
bool left; /**< Whether overflow happened or not. */
size_t right; /**< Multiplication result. */
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2))
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV(). People don't use this
* directly.
*
* @param[out] store Pointer to a variable.
* @param[in] len Requested number of bytes to allocate.
* @return Allocated `len` bytes array.
* @post `store` holds the corresponding tmp buffer object.
*/
void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2,3))
RBIMPL_ATTR_NONNULL(())
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
* directly.
*
* @param[out] store Pointer to a variable.
* @param[in] len Requested number of bytes to allocate.
* @param[in] count Number of elements in an array.
* @return Allocated `len` bytes array.
* @post `store` holds the corresponding tmp buffer object.
*
* @internal
*
* Although the meaning of `count` variable is clear, @shyouhei doesn't
* understand its needs.
*/
void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count);
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV_END(). People don't use this
* directly.
*
* @param[out] store Pointer to a variable.
* @pre `store` is a NULL, or a pointer to a tmp buffer object.
* @post `*store` is ::RUBY_Qfalse.
* @post The object formerly stored in `store` is destroyed.
*/
void rb_free_tmp_buffer(volatile VALUE *store);
RBIMPL_ATTR_NORETURN()
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
* directly.
*
* @param[in] x Arbitrary value.
* @param[in] y Arbitrary value.
* @exception rb_eArgError `x` * `y` would integer overflow.
*/
void ruby_malloc_size_overflow(size_t x, size_t y);
#ifdef HAVE_RB_GC_GUARDED_PTR_VAL
volatile VALUE *rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val);
#endif
RBIMPL_SYMBOL_EXPORT_END()
#ifdef _MSC_VER
# pragma optimize("", off)
/**
* @private
*
* This is an implementation detail of #RB_GC_GUARD(). People don't use this
* directly.
*
* @param[in] ptr A pointer to an on-stack C variable.
* @return `ptr` as-is.
*/
static inline volatile VALUE *
rb_gc_guarded_ptr(volatile VALUE *ptr)
{
return ptr;
}
# pragma optimize("", on)
#endif
/**
* @deprecated This function was an implementation detail of old
* #RB_ALLOCV_N(). We no longer use it. @shyouhei suspects that
* there are no actual usage now. However it was not marked as
* private before. We cannot delete it any longer.
* @param[in] a Arbitrary value.
* @param[in] b Arbitrary value.
* @param[in] max Possible maximum value.
* @param[out] c A pointer to return the computation result.
* @retval 1 `c` is insane.
* @retval 0 `c` is sane.
* @post `c` holds `a` * `b`, but could be overflowed.
*/
static inline int
rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c)
{
#ifdef DSIZE_T
RB_GNUC_EXTENSION DSIZE_T da, db, c2;
da = a;
db = b;
c2 = da * db;
if (c2 > max) return 1;
*c = RBIMPL_CAST((size_t)c2);
#else
if (b != 0 && a > max / b) return 1;
*c = a * b;
#endif
return 0;
}
#if defined(__DOXYGEN__)
RBIMPL_ATTR_CONSTEXPR(CXX14)
#elif RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70507 */
#elif RBIMPL_COMPILER_SINCE(Clang, 7, 0, 0)
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://bugs.llvm.org/show_bug.cgi?id=37633 */
#endif
RBIMPL_ATTR_CONST()
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
* directly.
*
* @param[in] x Arbitrary value.
* @param[in] y Arbitrary value.
* @return `{ left, right }`, where `left` is whether there is an integer
* overflow or not, and `right` is a (possibly overflowed) result
* of `x` * `y`.
*
* @internal
*
* This is in fact also an implementation detail of ruby_xmalloc2() etc.
*/
static inline struct rbimpl_size_mul_overflow_tag
rbimpl_size_mul_overflow(size_t x, size_t y)
{
struct rbimpl_size_mul_overflow_tag ret = { false, 0, };
#if RBIMPL_HAS_BUILTIN(__builtin_mul_overflow)
ret.left = __builtin_mul_overflow(x, y, &ret.right);
#elif defined(DSIZE_T)
RB_GNUC_EXTENSION DSIZE_T dx = x;
RB_GNUC_EXTENSION DSIZE_T dy = y;
RB_GNUC_EXTENSION DSIZE_T dz = dx * dy;
ret.left = dz > SIZE_MAX;
ret.right = RBIMPL_CAST((size_t)dz);
#elif defined(_MSC_VER) && defined(_WIN64)
unsigned __int64 dp = 0;
unsigned __int64 dz = _umul128(x, y, &dp);
ret.left = RBIMPL_CAST((bool)dp);
ret.right = RBIMPL_CAST((size_t)dz);
#else
/* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */
ret.left = (y != 0) && (x > SIZE_MAX / y);
ret.right = x * y;
#endif
return ret;
}
/**
* @private
*
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
* directly.
*
* @param[in] x Arbitrary value.
* @param[in] y Arbitrary value.
* @exception rb_eArgError Multiplication could integer overflow.
* @return `x` * `y`.
*
* @internal
*
* This is in fact also an implementation detail of ruby_xmalloc2() etc.
*/
static inline size_t
rbimpl_size_mul_or_raise(size_t x, size_t y)
{
struct rbimpl_size_mul_overflow_tag size =
rbimpl_size_mul_overflow(x, y);
if (RB_LIKELY(! size.left)) {
return size.right;
}
else {
ruby_malloc_size_overflow(x, y);
RBIMPL_UNREACHABLE_RETURN(0);
}
}
/**
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
* directly.
*
* @param[out] store Pointer to a variable.
* @param[in] count Number of elements in an array.
* @param[in] elsize Size of each elements.
* @return Region of `count` * `elsize` bytes.
* @post `store` holds the corresponding tmp buffer object.
*
* @internal
*
* We might want to deprecate this function and make a `rbimpl_` counterpart.
*/
static inline void *
rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
{
const size_t total_size = rbimpl_size_mul_or_raise(count, elsize);
const size_t cnt = (total_size + sizeof(VALUE) - 1) / sizeof(VALUE);
return rb_alloc_tmp_buffer_with_count(store, total_size, cnt);
}
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_RETURNS_NONNULL()
/* At least since 2004, glibc's <string.h> annotates memcpy to be
* __attribute__((__nonnull__(1, 2))). However it is safe to pass NULL to the
* source pointer, if n is 0. Let's wrap memcpy. */
static inline void *
ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
{
if (n) {
return memcpy(dest, src, n);
}
else {
return dest;
}
}
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_MEMORY_H */
include/ruby/internal/cast.h 0000644 00000004432 15040330606 0012067 0 ustar 00 #ifndef RBIMPL_CAST_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CAST_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines RBIMPL_CAST.
*
* This casting macro makes sense only inside of other macros that are part of
* public headers. They could be used from C++, and C-style casts could issue
* warnings. Ruby internals are pure C so they should not bother.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/warning_push.h"
#if ! defined(__cplusplus)
# define RBIMPL_CAST(expr) (expr)
#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# /* g++ has -Wold-style-cast since 1997 or so, but its _Pragma is broken. */
# /* See https://gcc.godbolt.org/z/XWhU6J */
# define RBIMPL_CAST(expr) (expr)
# pragma GCC diagnostic ignored "-Wold-style-cast"
#elif RBIMPL_HAS_WARNING("-Wold-style-cast")
# define RBIMPL_CAST(expr) \
RBIMPL_WARNING_PUSH() \
RBIMPL_WARNING_IGNORED(-Wold-style-cast) \
(expr) \
RBIMPL_WARNING_POP()
#else
# define RBIMPL_CAST(expr) (expr)
#endif
#endif /* RBIMPL_CAST_H */
include/ruby/internal/fl_type.h 0000644 00000104114 15040330606 0012575 0 ustar 00 #ifndef RBIMPL_FL_TYPE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_FL_TYPE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines enum ::ruby_fl_type.
*/
#include "ruby/internal/config.h" /* for ENUM_OVER_INT */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/flag_enum.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/extension.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"
#include "ruby/defines.h"
/** @cond INTERNAL_MACRO */
#if RBIMPL_HAS_EXTENSION(enumerator_attributes)
# define RBIMPL_HAVE_ENUM_ATTRIBUTE 1
#elif RBIMPL_COMPILER_SINCE(GCC, 6, 0, 0)
# define RBIMPL_HAVE_ENUM_ATTRIBUTE 1
#endif
#ifdef ENUM_OVER_INT
# define RBIMPL_WIDER_ENUM 1
#elif SIZEOF_INT * CHAR_BIT > 12+19+1
# define RBIMPL_WIDER_ENUM 1
#else
# define RBIMPL_WIDER_ENUM 0
#endif
/** @endcond */
#define FL_SINGLETON RBIMPL_CAST((VALUE)RUBY_FL_SINGLETON) /**< @old{RUBY_FL_SINGLETON} */
#define FL_WB_PROTECTED RBIMPL_CAST((VALUE)RUBY_FL_WB_PROTECTED) /**< @old{RUBY_FL_WB_PROTECTED} */
#define FL_PROMOTED0 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED0) /**< @old{RUBY_FL_PROMOTED0} */
#define FL_PROMOTED1 RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED1) /**< @old{RUBY_FL_PROMOTED1} */
#define FL_FINALIZE RBIMPL_CAST((VALUE)RUBY_FL_FINALIZE) /**< @old{RUBY_FL_FINALIZE} */
#define FL_TAINT RBIMPL_CAST((VALUE)RUBY_FL_TAINT) /**< @old{RUBY_FL_TAINT} */
#define FL_SHAREABLE RBIMPL_CAST((VALUE)RUBY_FL_SHAREABLE) /**< @old{RUBY_FL_SHAREABLE} */
#define FL_UNTRUSTED RBIMPL_CAST((VALUE)RUBY_FL_UNTRUSTED) /**< @old{RUBY_FL_UNTRUSTED} */
#define FL_SEEN_OBJ_ID RBIMPL_CAST((VALUE)RUBY_FL_SEEN_OBJ_ID) /**< @old{RUBY_FL_SEEN_OBJ_ID} */
#define FL_EXIVAR RBIMPL_CAST((VALUE)RUBY_FL_EXIVAR) /**< @old{RUBY_FL_EXIVAR} */
#define FL_FREEZE RBIMPL_CAST((VALUE)RUBY_FL_FREEZE) /**< @old{RUBY_FL_FREEZE} */
#define FL_USHIFT RBIMPL_CAST((VALUE)RUBY_FL_USHIFT) /**< @old{RUBY_FL_USHIFT} */
#define FL_USER0 RBIMPL_CAST((VALUE)RUBY_FL_USER0) /**< @old{RUBY_FL_USER0} */
#define FL_USER1 RBIMPL_CAST((VALUE)RUBY_FL_USER1) /**< @old{RUBY_FL_USER1} */
#define FL_USER2 RBIMPL_CAST((VALUE)RUBY_FL_USER2) /**< @old{RUBY_FL_USER2} */
#define FL_USER3 RBIMPL_CAST((VALUE)RUBY_FL_USER3) /**< @old{RUBY_FL_USER3} */
#define FL_USER4 RBIMPL_CAST((VALUE)RUBY_FL_USER4) /**< @old{RUBY_FL_USER4} */
#define FL_USER5 RBIMPL_CAST((VALUE)RUBY_FL_USER5) /**< @old{RUBY_FL_USER5} */
#define FL_USER6 RBIMPL_CAST((VALUE)RUBY_FL_USER6) /**< @old{RUBY_FL_USER6} */
#define FL_USER7 RBIMPL_CAST((VALUE)RUBY_FL_USER7) /**< @old{RUBY_FL_USER7} */
#define FL_USER8 RBIMPL_CAST((VALUE)RUBY_FL_USER8) /**< @old{RUBY_FL_USER8} */
#define FL_USER9 RBIMPL_CAST((VALUE)RUBY_FL_USER9) /**< @old{RUBY_FL_USER9} */
#define FL_USER10 RBIMPL_CAST((VALUE)RUBY_FL_USER10) /**< @old{RUBY_FL_USER10} */
#define FL_USER11 RBIMPL_CAST((VALUE)RUBY_FL_USER11) /**< @old{RUBY_FL_USER11} */
#define FL_USER12 RBIMPL_CAST((VALUE)RUBY_FL_USER12) /**< @old{RUBY_FL_USER12} */
#define FL_USER13 RBIMPL_CAST((VALUE)RUBY_FL_USER13) /**< @old{RUBY_FL_USER13} */
#define FL_USER14 RBIMPL_CAST((VALUE)RUBY_FL_USER14) /**< @old{RUBY_FL_USER14} */
#define FL_USER15 RBIMPL_CAST((VALUE)RUBY_FL_USER15) /**< @old{RUBY_FL_USER15} */
#define FL_USER16 RBIMPL_CAST((VALUE)RUBY_FL_USER16) /**< @old{RUBY_FL_USER16} */
#define FL_USER17 RBIMPL_CAST((VALUE)RUBY_FL_USER17) /**< @old{RUBY_FL_USER17} */
#define FL_USER18 RBIMPL_CAST((VALUE)RUBY_FL_USER18) /**< @old{RUBY_FL_USER18} */
#define FL_USER19 RBIMPL_CAST((VALUE)(unsigned int)RUBY_FL_USER19) /**< @old{RUBY_FL_USER19} */
#define ELTS_SHARED RUBY_ELTS_SHARED /**< @old{RUBY_ELTS_SHARED} */
#define RB_OBJ_FREEZE rb_obj_freeze_inline /**< @alias{rb_obj_freeze_inline} */
/** @cond INTERNAL_MACRO */
#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED
#define RB_FL_ABLE RB_FL_ABLE
#define RB_FL_ALL RB_FL_ALL
#define RB_FL_ALL_RAW RB_FL_ALL_RAW
#define RB_FL_ANY RB_FL_ANY
#define RB_FL_ANY_RAW RB_FL_ANY_RAW
#define RB_FL_REVERSE RB_FL_REVERSE
#define RB_FL_REVERSE_RAW RB_FL_REVERSE_RAW
#define RB_FL_SET RB_FL_SET
#define RB_FL_SET_RAW RB_FL_SET_RAW
#define RB_FL_TEST RB_FL_TEST
#define RB_FL_TEST_RAW RB_FL_TEST_RAW
#define RB_FL_UNSET RB_FL_UNSET
#define RB_FL_UNSET_RAW RB_FL_UNSET_RAW
#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW
#define RB_OBJ_FROZEN RB_OBJ_FROZEN
#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW
#define RB_OBJ_INFECT RB_OBJ_INFECT
#define RB_OBJ_INFECT_RAW RB_OBJ_INFECT_RAW
#define RB_OBJ_TAINT RB_OBJ_TAINT
#define RB_OBJ_TAINTABLE RB_OBJ_TAINTABLE
#define RB_OBJ_TAINTED RB_OBJ_TAINTED
#define RB_OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW
#define RB_OBJ_TAINT_RAW RB_OBJ_TAINT_RAW
#define RB_OBJ_UNTRUST RB_OBJ_TAINT
#define RB_OBJ_UNTRUSTED RB_OBJ_TAINTED
/** @endcond */
/**
* @defgroup deprecated_macros Deprecated macro APIs
* @{
* These macros are deprecated. Prefer their `RB_`-prefixed versions.
*/
#define FL_ABLE RB_FL_ABLE /**< @old{RB_FL_ABLE} */
#define FL_ALL RB_FL_ALL /**< @old{RB_FL_ALL} */
#define FL_ALL_RAW RB_FL_ALL_RAW /**< @old{RB_FL_ALL_RAW} */
#define FL_ANY RB_FL_ANY /**< @old{RB_FL_ANY} */
#define FL_ANY_RAW RB_FL_ANY_RAW /**< @old{RB_FL_ANY_RAW} */
#define FL_REVERSE RB_FL_REVERSE /**< @old{RB_FL_REVERSE} */
#define FL_REVERSE_RAW RB_FL_REVERSE_RAW /**< @old{RB_FL_REVERSE_RAW} */
#define FL_SET RB_FL_SET /**< @old{RB_FL_SET} */
#define FL_SET_RAW RB_FL_SET_RAW /**< @old{RB_FL_SET_RAW} */
#define FL_TEST RB_FL_TEST /**< @old{RB_FL_TEST} */
#define FL_TEST_RAW RB_FL_TEST_RAW /**< @old{RB_FL_TEST_RAW} */
#define FL_UNSET RB_FL_UNSET /**< @old{RB_FL_UNSET} */
#define FL_UNSET_RAW RB_FL_UNSET_RAW /**< @old{RB_FL_UNSET_RAW} */
#define OBJ_FREEZE RB_OBJ_FREEZE /**< @old{RB_OBJ_FREEZE} */
#define OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW /**< @old{RB_OBJ_FREEZE_RAW} */
#define OBJ_FROZEN RB_OBJ_FROZEN /**< @old{RB_OBJ_FROZEN} */
#define OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW /**< @old{RB_OBJ_FROZEN_RAW} */
#define OBJ_INFECT RB_OBJ_INFECT /**< @old{RB_OBJ_INFECT} */
#define OBJ_INFECT_RAW RB_OBJ_INFECT_RAW /**< @old{RB_OBJ_INFECT_RAW} */
#define OBJ_TAINT RB_OBJ_TAINT /**< @old{RB_OBJ_TAINT} */
#define OBJ_TAINTABLE RB_OBJ_TAINTABLE /**< @old{RB_OBJ_TAINT_RAW} */
#define OBJ_TAINTED RB_OBJ_TAINTED /**< @old{RB_OBJ_TAINTED} */
#define OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW /**< @old{RB_OBJ_TAINTED_RAW} */
#define OBJ_TAINT_RAW RB_OBJ_TAINT_RAW /**< @old{RB_OBJ_TAINT_RAW} */
#define OBJ_UNTRUST RB_OBJ_UNTRUST /**< @old{RB_OBJ_TAINT} */
#define OBJ_UNTRUSTED RB_OBJ_UNTRUSTED /**< @old{RB_OBJ_TAINTED} */
/** @} */
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
*/
enum ruby_fl_ushift {
/**
* Number of bits in ::ruby_fl_type that are _not_ open to users. This is
* an implementation detail. Please ignore.
*/
RUBY_FL_USHIFT = 12
};
/* > The expression that defines the value of an enumeration constant shall be
* > an integer constant expression that has a value representable as an `int`.
*
* -- ISO/IEC 9899:2018 section 6.7.2.2
*
* So ENUM_OVER_INT situation is an extension to the standard. Note however
* that we do not support 16 bit `int` environment. */
RB_GNUC_EXTENSION
/**
* The flags. Each ruby objects have their own characteristics apart from
* their classes. For instance whether an object is frozen or not is not
* controlled by its class. This is the type that represents such properties.
*
* @note About the `FL_USER` terminology: the "user" here does not necessarily
* mean only you. For instance struct ::RString instances use these
* bits to cache their encodings etc. Devs discussed about this topic,
* reached their consensus that ::RUBY_T_DATA is the only valid data
* structure that can use these bits; other data structures including
* ::RUBY_T_OBJECT use these bits for their own purpose. See also
* https://bugs.ruby-lang.org/issues/18059
*/
enum
RBIMPL_ATTR_FLAG_ENUM()
ruby_fl_type {
/**
* @deprecated This flag once was a thing back in the old days, but makes
* no sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @internal
*
* The reality is our GC no longer remembers write barriers inside of each
* objects, to use dedicated bitmap instead. But this flag is still used
* internally. The current usages of this flag should be something
* different, which is unclear to @shyouhei.
*/
RUBY_FL_WB_PROTECTED = (1<<5),
/**
* This flag has something to do with our garbage collector. These days
* ruby objects are "generational". There are those who are young and
* those who are old. Young objects are prone to die; monitored relatively
* extensively by the garbage collector. OTOH old objects tend to live
* longer. They are relatively rarely considered. This flag is set when a
* object experienced promotion i.e. survived a garbage collection.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_PROMOTED0 = (1<<5),
/**
* This flag has something to do with our garbage collector. These days
* ruby objects are "generational". There are those who are young and
* those who are old. Young objects are prone to die; monitored relatively
* extensively by the garbage collector. OTOH old objects tend to live
* longer. They are relatively rarely considered. This flag is set when a
* object experienced two promotions i.e. survived garbage collections
* twice.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_PROMOTED1 = (1<<6),
/**
* This flag has something to do with our garbage collector. These days
* ruby objects are "generational". There are those who are young and
* those who are old. Young objects are prone to die; monitored relatively
* extensively by the garbage collector. OTOH old objects tend to live
* longer. They are relatively rarely considered. This flag is set when a
* object experienced promotions i.e. survived more than one garbage
* collections.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1,
/**
* This flag has something to do with finalisers. A ruby object can have
* its finaliser, which is another object that evaluates when the target
* object is about to die. This flag is used to denote that there is an
* attached finaliser.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_FINALIZE = (1<<7),
/**
* @deprecated This flag once was a thing back in the old days, but makes
* no sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*/
RUBY_FL_TAINT
#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_TAINT)
#endif
= (1<<8),
/**
* This flag has something to do with Ractor. Multiple Ractors run without
* protecting each other. Sharing an object among Ractors are basically
* dangerous, disabled by default. This flag is used to bypass that
* restriction. Of course, you have to manually prevent race conditions
* then.
*
* This flag needs deep understanding of multithreaded programming. You
* would better not use it.
*/
RUBY_FL_SHAREABLE = (1<<8),
/**
* @deprecated This flag once was a thing back in the old days, but makes
* no sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*/
RUBY_FL_UNTRUSTED
#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
RBIMPL_ATTR_DEPRECATED(("trustedness turned out to be a wrong idea."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_UNTRUSTED)
#endif
= (1<<8),
/**
* This flag has something to do with object IDs. Unlike in the old days,
* an object's object ID (that a user can query using `Object#object_id`)
* is no longer its physical address represented using Ruby level integers.
* It is now a monotonic-increasing integer unrelated to the underlying
* memory arrangement. Object IDs are assigned when necessary; objects are
* born without one, and will eventually have such property when queried.
* The interpreter has to manage which one is which. This is the flag that
* helps the management. Objects with this flag set are the ones with
* object IDs assigned.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_SEEN_OBJ_ID = (1<<9),
/**
* This flag has something to do with instance variables. 3rd parties need
* not know, but there are several ways to store an object's instance
* variables. Objects with this flag use so-called "generic" backend
* storage. This distinction is purely an implementation detail. People
* need not be aware of this working behind-the-scene.
*
* @internal
*
* As of writing everything except ::RObject and RModule use this scheme.
*/
RUBY_FL_EXIVAR = (1<<10),
/**
* This flag has something to do with data immutability. When this flag is
* set an object is considered "frozen". No modification are expected to
* happen beyond that point for the particular object. Immutability is
* basically considered to be a good property these days. Library authors
* are expected to obey. Test this bit before you touch a data structure.
*
* @see rb_check_frozen()
*/
RUBY_FL_FREEZE = (1<<11),
/** (@shyouhei doesn't know how to excude this macro from doxygen). */
#define RBIMPL_FL_USER_N(n) RUBY_FL_USER##n = (1<<(RUBY_FL_USHIFT+n))
RBIMPL_FL_USER_N(0), /**< User-defined flag. */
RBIMPL_FL_USER_N(1), /**< User-defined flag. */
RBIMPL_FL_USER_N(2), /**< User-defined flag. */
RBIMPL_FL_USER_N(3), /**< User-defined flag. */
RBIMPL_FL_USER_N(4), /**< User-defined flag. */
RBIMPL_FL_USER_N(5), /**< User-defined flag. */
RBIMPL_FL_USER_N(6), /**< User-defined flag. */
RBIMPL_FL_USER_N(7), /**< User-defined flag. */
RBIMPL_FL_USER_N(8), /**< User-defined flag. */
RBIMPL_FL_USER_N(9), /**< User-defined flag. */
RBIMPL_FL_USER_N(10), /**< User-defined flag. */
RBIMPL_FL_USER_N(11), /**< User-defined flag. */
RBIMPL_FL_USER_N(12), /**< User-defined flag. */
RBIMPL_FL_USER_N(13), /**< User-defined flag. */
RBIMPL_FL_USER_N(14), /**< User-defined flag. */
RBIMPL_FL_USER_N(15), /**< User-defined flag. */
RBIMPL_FL_USER_N(16), /**< User-defined flag. */
RBIMPL_FL_USER_N(17), /**< User-defined flag. */
RBIMPL_FL_USER_N(18), /**< User-defined flag. */
#ifdef ENUM_OVER_INT
RBIMPL_FL_USER_N(19), /**< User-defined flag. */
#else
# define RUBY_FL_USER19 (RBIMPL_VALUE_ONE<<(RUBY_FL_USHIFT+19))
#endif
#undef RBIMPL_FL_USER_N
#undef RBIMPL_WIDER_ENUM
/**
* This flag has something to do with data structures. Over time, ruby
* evolved to reduce memory footprints. One of such attempt is so-called
* copy-on-write, which delays duplication of resources until ultimately
* necessary. Some data structures share this scheme. For example
* multiple instances of struct ::RArray could point identical memory
* region in common, as long as they don't differ. As people favour
* immutable style of programming than before, this situation is getting
* more and more common. Because such "shared" memory regions have nuanced
* ownership by nature, each structures need special care for them. This
* flag is used to distinguish such shared constructs.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_ELTS_SHARED = RUBY_FL_USER2,
/**
* This flag has something to do with an object's class. There are kind of
* classes called "singleton class", each of which have exactly one
* instance. What is interesting about singleton classes is that they are
* created _after_ their instance were instantiated, like this:
*
* ```ruby
* foo = Object.new # foo is an instance of Object...
* bar = foo.singleton_class # foo is now an instance of bar.
* ```
*
* Here as you see `bar` is a singleton class of `foo`, which is injected
* into `foo`'s inheritance tree in a different statement (== distinct
* sequence point). In order to achieve this property singleton classes
* are special-cased in the interpreter. There is one bit flag that
* distinguishes if a class is a singleton class or not, and this is it.
*
* @internal
*
* But honestly, @shyouhei doesn't think this flag should be visible from
* 3rd parties. It must be an implementation detail that they should never
* know. Might better be hidden.
*/
RUBY_FL_SINGLETON = RUBY_FL_USER0,
};
enum {
/**
* @deprecated This flag once was a thing back in the old days, but makes
* no sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*/
RUBY_FL_DUPPED
#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
RBIMPL_ATTR_DEPRECATED(("It seems there is no actual usage of this enum."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_DUPPED)
#endif
= (int)RUBY_T_MASK | (int)RUBY_FL_EXIVAR
};
#undef RBIMPL_HAVE_ENUM_ATTRIBUTE
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is an implementation detail of #RB_OBJ_FREEZE(). People don't use it
* directly.
*
* @param[out] klass A singleton class.
* @post `klass` gets frozen.
*/
void rb_freeze_singleton_class(VALUE klass);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_FORCEINLINE()
/**
* Checks if the object is flaggable. There are some special cases (most
* notably ::RUBY_Qfalse) where appending a flag to an object is not possible.
* This function can detect that.
*
* @param[in] obj Object in question
* @retval true It is flaggable.
* @retval false No it isn't.
*/
static bool
RB_FL_ABLE(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
return false;
}
else if (RB_TYPE_P(obj, RUBY_T_NODE)) {
return false;
}
else {
return true;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_TEST(). 3rd parties need not use
* this. Just always use RB_FL_TEST().
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @pre The object must not be an enum ::ruby_special_consts.
* @return `obj`'s flags, masked by `flags`.
*/
static inline VALUE
RB_FL_TEST_RAW(VALUE obj, VALUE flags)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
return RBASIC(obj)->flags & flags;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Tests if the given flag(s) are set or not. You can pass multiple flags at
* once:
*
* ```CXX
* auto obj = rb_eval_string("...");
* if (RB_FL_TEST(obj, RUBY_FL_FREEZE | RUBY_FL_SHAREABLE)) {
* printf("Ractor ready!\n");
* }
* ```
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @return `obj`'s flags, masked by `flags`.
* @note It is intentional for this function to return ::VALUE. The
* return value could be passed to RB_FL_STE() etc.
*/
static inline VALUE
RB_FL_TEST(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
return RB_FL_TEST_RAW(obj, flags);
}
else {
return RBIMPL_VALUE_NULL;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_ANY(). 3rd parties need not use
* this. Just always use RB_FL_ANY().
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @retval true The object has any of the flags set.
* @retval false No it doesn't at all.
* @pre The object must not be an enum ::ruby_special_consts.
*/
static inline bool
RB_FL_ANY_RAW(VALUE obj, VALUE flags)
{
return RB_FL_TEST_RAW(obj, flags);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to RB_FL_TEST(), except it returns bool.
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @retval true The object has any of the flags set.
* @retval false No it doesn't at all.
*/
static inline bool
RB_FL_ANY(VALUE obj, VALUE flags)
{
return RB_FL_TEST(obj, flags);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_ALL(). 3rd parties need not use
* this. Just always use RB_FL_ALL().
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @retval true The object has all of the flags set.
* @retval false The object lacks any of the flags.
* @pre The object must not be an enum ::ruby_special_consts.
*/
static inline bool
RB_FL_ALL_RAW(VALUE obj, VALUE flags)
{
return RB_FL_TEST_RAW(obj, flags) == flags;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to RB_FL_ANY(), except it mandates all passed flags be set.
*
* @param[in] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @retval true The object has all of the flags set.
* @retval false The object lacks any of the flags.
*/
static inline bool
RB_FL_ALL(VALUE obj, VALUE flags)
{
return RB_FL_TEST(obj, flags) == flags;
}
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
* This is an implenentation detail of RB_FL_SET(). 3rd parties need not use
* this. Just always use RB_FL_SET().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` set.
*
* @internal
*
* This is function is here to annotate a part of RB_FL_SET_RAW() as
* `__declspec(noalias)`.
*/
static inline void
rbimpl_fl_set_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags |= flags;
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_SET(). 3rd parties need not use
* this. Just always use RB_FL_SET().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` set.
*/
static inline void
RB_FL_SET_RAW(VALUE obj, VALUE flags)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
rbimpl_fl_set_raw_raw(RBASIC(obj), flags);
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Sets the given flag(s).
*
* ```CXX
* auto v = rb_eval_string("...");
* RB_FL_SET(v, RUBY_FL_FREEZE);
* ```
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` set.
*/
static inline void
RB_FL_SET(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_SET_RAW(obj, flags);
}
}
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
* This is an implenentation detail of RB_FL_UNSET(). 3rd parties need not use
* this. Just always use RB_FL_UNSET().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` cleared.
*
* @internal
*
* This is function is here to annotate a part of RB_FL_UNSET_RAW() as
* `__declspec(noalias)`.
*/
static inline void
rbimpl_fl_unset_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags &= ~flags;
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_UNSET(). 3rd parties need not use
* this. Just always use RB_FL_UNSET().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` cleared.
*/
static inline void
RB_FL_UNSET_RAW(VALUE obj, VALUE flags)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
rbimpl_fl_unset_raw_raw(RBASIC(obj), flags);
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Clears the given flag(s).
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` cleard.
*/
static inline void
RB_FL_UNSET(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_UNSET_RAW(obj, flags);
}
}
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
*
* This is an implenentation detail of RB_FL_REVERSE(). 3rd parties need not
* use this. Just always use RB_FL_REVERSE().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` reversed.
*
* @internal
*
* This is function is here to annotate a part of RB_FL_REVERSE_RAW() as
* `__declspec(noalias)`.
*/
static inline void
rbimpl_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags)
{
obj->flags ^= flags;
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_FL_REVERSE(). 3rd parties need not
* use this. Just always use RB_FL_REVERSE().
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` cleared.
*/
static inline void
RB_FL_REVERSE_RAW(VALUE obj, VALUE flags)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
rbimpl_fl_reverse_raw_raw(RBASIC(obj), flags);
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* Reverses the flags. This function is here mainly for symmetry on set/unset.
* Rarely used in practice.
*
* @param[out] obj Object in question.
* @param[in] flags A set of enum ::ruby_fl_type.
* @post `obj` has `flags` reversed.
*/
static inline void
RB_FL_REVERSE(VALUE obj, VALUE flags)
{
if (RB_FL_ABLE(obj)) {
RB_FL_REVERSE_RAW(obj, flags);
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
* @return false always.
*/
static inline bool
RB_OBJ_TAINTABLE(VALUE obj)
{
return false;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
* @return false always.
*/
static inline VALUE
RB_OBJ_TAINTED_RAW(VALUE obj)
{
return false;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
* @return false always.
*/
static inline bool
RB_OBJ_TAINTED(VALUE obj)
{
return false;
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
*/
static inline void
RB_OBJ_TAINT_RAW(VALUE obj)
{
return;
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] obj Object in question.
*/
static inline void
RB_OBJ_TAINT(VALUE obj)
{
return;
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] dst Victim object.
* @param[in] src Infectant object.
*/
static inline void
RB_OBJ_INFECT_RAW(VALUE dst, VALUE src)
{
return;
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
* @deprecated This function once was a thing in the old days, but makes no
* sense any longer today. Exists here for backwards
* compatibility only. You can safely forget about it.
*
* @param[in] dst Victim object.
* @param[in] src Infectant object.
*/
static inline void
RB_OBJ_INFECT(VALUE dst, VALUE src)
{
return;
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_OBJ_FROZEN(). 3rd parties need not
* use this. Just always use RB_OBJ_FROZEN().
*
* @param[in] obj Object in question.
* @retval RUBY_FL_FREEZE Yes it is.
* @retval 0 No it isn't.
*
* @internal
*
* It is intentional not to return bool here. There is a place in ruby core
* (namely `class.c:singleton_class_of()`) where return value of this function
* is passed to RB_FL_SET_RAW().
*/
static inline VALUE
RB_OBJ_FROZEN_RAW(VALUE obj)
{
return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Checks if an object is frozen.
*
* @param[in] obj Object in question.
* @retval true Yes it is.
* @retval false No it isn't.
*/
static inline bool
RB_OBJ_FROZEN(VALUE obj)
{
if (! RB_FL_ABLE(obj)) {
return true;
}
else {
return RB_OBJ_FROZEN_RAW(obj);
}
}
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is an implenentation detail of RB_OBJ_FREEZE(). 3rd parties need not
* use this. Just always use RB_OBJ_FREEZE().
*
* @param[out] obj Object in question.
*/
static inline void
RB_OBJ_FREEZE_RAW(VALUE obj)
{
RB_FL_SET_RAW(obj, RUBY_FL_FREEZE);
}
RUBY_SYMBOL_EXPORT_BEGIN
void rb_obj_freeze_inline(VALUE obj);
RUBY_SYMBOL_EXPORT_END
#endif /* RBIMPL_FL_TYPE_H */
include/ruby/internal/method.h 0000644 00000016121 15040330606 0012413 0 ustar 00 #ifndef RBIMPL_METHOD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_METHOD_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Creation and modification of Ruby methods.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"
/**
* @defgroup defmethod Defining methods
*
* There are some APIs to define a method from C.
* These API takes a C function as a method body.
*
* ### Method body functions
*
* Method body functions must return a VALUE and
* can be one of the following form:
*
* #### Fixed number of parameters
*
* This form is a normal C function, excepting it takes
* a receiver object as the first argument.
*
* ```CXX
* static VALUE my_method(VALUE self, VALUE x, VALUE y);
* ```
*
* #### argc and argv style
*
* This form takes three parameters: argc, argv and self.
* self is the receiver. argc is the number of arguments.
* argv is a pointer to an array of the arguments.
*
* ```CXX
* static VALUE my_method(int argc, VALUE *argv, VALUE self);
* ```
*
* #### Ruby array style
*
* This form takes two parameters: self and args.
* self is the receiver. args is an Array object which
* contains the arguments.
*
* ```CXX
* static VALUE my_method(VALUE self, VALUE args);
* ```
*
* ### Number of parameters
*
* Method defining APIs takes the number of parameters which the
* method will takes. This number is called argc.
* argc can be:
*
* - Zero or positive number.
* This means the method body function takes a fixed number of parameters.
*
* - `-1`.
* This means the method body function is "argc and argv" style.
*
* - `-2`.
* This means the method body function is "self and args" style.
*
* @{
*/
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
* Defines a method.
*
* @param[out] klass A module or a class.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_method
*/
void rb_define_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a module function for a module.
*
* @param[out] klass A module or a class.
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_module_function
*/
void rb_define_module_function(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a global function.
*
* @param[in] mid Name of the function.
* @param[in] func The method body.
* @param[in] arity The number of parameters. See @ref defmethod.
* @note There are in fact 18 different prototypes for func.
* @see ::ruby::backward::cxxanyargs::define_method::rb_define_global_function
*/
void rb_define_global_function(const char *mid, VALUE (*func)(ANYARGS), int arity);
RBIMPL_ATTR_NONNULL(())
/**
* Defines an undef of a method. -- What?
*
* In ruby, there are two separate concepts called "undef" and "remove_method".
* The thing you imagine when you "un-define" a method is remove_method. This
* one on the other hand is masking of a previous method definition. Suppose
* for instance:
*
* ```ruby
* class Foo
* def foo
* end
* end
*
* class Bar < Foo
* def bar
* foo
* end
* end
*
* class Baz < Foo
* undef foo # <--- (*1)
* end
* ```
*
* This `undef foo` at `(*1)` must not eliminate `Foo#foo`, because that method
* is also used from `Bar#bar`. So instead of physically executing the target
* method, `undef` inserts a special filtering entry to the class (`Baz` this
* case). That entry, when called, acts as if there were no methods at all.
* But the original can still be accessible, via ways like `Bar#bar` above.
*
* @param[out] klass The class to insert an undef.
* @param[in] name Name of the undef.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @see rb_remove_method
*/
void rb_undef_method(VALUE klass, const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* Defines an alias of a method.
*
* @param[in,out] klass The class which the original method belongs
* to; this is also where the new method will
* belong to.
* @param[in] dst A new name for the method.
* @param[in] src The original name of the method.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError There is no such method named as `src` in
* `klass`.
*
* @internal
*
* Above description is in fact a bit inaccurate because it ignores
* Refinements.
*/
void rb_define_alias(VALUE klass, const char *dst, const char *src);
RBIMPL_ATTR_NONNULL(())
/**
* Defines public accessor method(s) for an attribute.
*
* @param[out] klass The class which the attribute will belong to.
* @param[in] name Name of the attribute.
* @param[in] read Whether to define a getter method.
* @param[in] write Whether to define a setter method.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError `name` invalid as an attr e.g. an operator.
*/
void rb_define_attr(VALUE klass, const char *name, int read, int write);
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_METHOD_H */
include/ruby/internal/compiler_is.h 0000644 00000004071 15040330606 0013441 0 ustar 00 #ifndef RBIMPL_COMPILER_IS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_COMPILER_IS.
*/
/**
* @brief Checks if the compiler is of given brand.
* @param cc Compiler brand, like `MSVC`.
* @retval true It is.
* @retval false It isn't.
*/
#define RBIMPL_COMPILER_IS(cc) RBIMPL_COMPILER_IS_ ## cc
#include "ruby/internal/compiler_is/apple.h"
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/gcc.h"
#include "ruby/internal/compiler_is/intel.h"
#include "ruby/internal/compiler_is/msvc.h"
#include "ruby/internal/compiler_is/sunpro.h"
/* :TODO: Other possible compilers to support:
*
* - IBM XL: recent XL are clang-backended so some tweaks like we do for
* Apple's might be needed.
*
* - ARM's armclang: ditto, it can be clang-backended. */
#endif /* RBIMPL_COMPILER_IS_H */
include/ruby/internal/xmalloc.h 0000644 00000042115 15040330606 0012574 0 ustar 00 #ifndef RBIMPL_XMALLOC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_XMALLOC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Declares ::ruby_xmalloc().
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/nodiscard.h"
#include "ruby/internal/attr/noexcept.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
/**
* @private
* @warning Do not touch this macro.
* @warning It is an implementation detail.
* @warning It was a failure at the first place to let you know about it.
* @warning The value of this macro must match for ruby itself and all
* extension libraries, otherwise serious memory corruption shall
* occur.
*/
#ifndef USE_GC_MALLOC_OBJ_INFO_DETAILS
# define USE_GC_MALLOC_OBJ_INFO_DETAILS 0
#endif
#define xmalloc ruby_xmalloc /**< @old{ruby_xmalloc} */
#define xmalloc2 ruby_xmalloc2 /**< @old{ruby_xmalloc2} */
#define xcalloc ruby_xcalloc /**< @old{ruby_xcalloc} */
#define xrealloc ruby_xrealloc /**< @old{ruby_xrealloc} */
#define xrealloc2 ruby_xrealloc2 /**< @old{ruby_xrealloc2} */
#define xfree ruby_xfree /**< @old{ruby_xfree} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1))
/**
* Allocates a storage instance. It is largely the same as system malloc(),
* except:
*
* - It raises Ruby exceptions instead of returning NULL, and
* - In case of `ENOMEM` it tries to GC to make some room.
*
* @param[in] size Requested amount of memory.
* @exception rb_eNoMemError No space left for `size` bytes allocation.
* @return A valid pointer to an allocated storage instance; which has at
* least `size` bytes width, with appropriate alignment detected by
* the underlying malloc() routine.
* @note It doesn't return NULL.
* @note Unlike some malloc() implementations, it allocates something and
* returns a meaningful value even when `size` is equal to zero.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
void *ruby_xmalloc(size_t size)
RBIMPL_ATTR_NOEXCEPT(malloc(size))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
/**
* Identical to ruby_xmalloc(), except it allocates `nelems` * `elemsiz` bytes.
* This is needed because the multiplication could integer overflow. On such
* situations Ruby does not try to allocate at all but raises Ruby level
* exceptions instead. If there is no integer overflow the behaviour is
* exactly the same as `ruby_xmalloc(nelems*elemsiz)`.
*
* @param[in] nelems Number of elements.
* @param[in] elemsiz Size of an element.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError `nelems` * `elemsiz` would overflow.
* @return A valid pointer to an allocated storage instance; which has at
* least `nelems` * `elemsiz` bytes width, with appropriate
* alignment detected by the underlying malloc() routine.
* @note It doesn't return NULL.
* @note Unlike some malloc() implementations, it allocates something and
* returns a meaningful value even when `nelems` or `elemsiz` or
* both are zero.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
void *ruby_xmalloc2(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(malloc(nelems * elemsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
/**
* Identical to ruby_xmalloc2(), except it returns a zero-filled storage
* instance. It can also be seen as a routine identical to ruby_xmalloc(),
* except it calls calloc() instead of malloc().
*
* @param[in] nelems Number of elements.
* @param[in] elemsiz Size of an element.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError `nelems` * `elemsiz` would overflow.
* @return A valid pointer to an allocated storage instance; which has at
* least `nelems` * `elemsiz` bytes width, with appropriate
* alignment detected by the underlying calloc() routine.
* @post The returned storage instance is filled with zeros.
* @note It doesn't return NULL.
* @note Unlike some calloc() implementations, it allocates something and
* returns a meaningful value even when `nelems` or `elemsiz` or
* both are zero.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
void *ruby_xcalloc(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(calloc(nelems, elemsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2))
/**
* Resize the storage instance.
*
* @param[in] ptr A valid pointer to a storage instance that was
* previously returned from either:
* - ruby_xmalloc(),
* - ruby_xmalloc2(),
* - ruby_xcalloc(),
* - ruby_xrealloc(), or
* - ruby_xrealloc2().
* @param[in] newsiz Requested new amount of memory.
* @exception rb_eNoMemError No space left for `newsiz` bytes allocation.
* @return A valid pointer to a (possibly newly allocated) storage
* instance; which has at least `newsiz` bytes width, with
* appropriate alignment detected by the underlying realloc()
* routine.
* @pre The passed pointer must point to a valid live storage instance.
* It is a failure to pass an already freed pointer.
* @post In case the function returns the passed pointer as-is, the
* storage instance that the pointer holds is either grown or
* shrunken to have at least `newsiz` bytes. Otherwise a valid
* pointer to a newly allocated storage instance is returned. In
* this case `ptr` is invalidated as if it was passed to
* ruby_xfree().
* @note It doesn't return NULL.
* @warning Unlike some realloc() implementations, passing zero to `newsiz`
* is not the same as calling ruby_xfree(), because this function
* never returns NULL. Something meaningful still returns then.
* @warning It is a failure not to check the return value. Do not assume
* anything on it. It could be either identical to, or distinct
* form the passed argument.
* @warning Do not assume anything on the alignment of the return value.
* There is no guarantee that it inherits the passed argument's
* one.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
void *ruby_xrealloc(void *ptr, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2,3))
/**
* Identical to ruby_xrealloc(), except it resizes the given storage instance
* to `newelems` * `newsiz` bytes. This is needed because the multiplication
* could integer overflow. On such situations Ruby does not try to touch the
* contents of argument pointer at all but raises Ruby level exceptions
* instead. If there is no integer overflow the behaviour is exactly the same
* as `ruby_xrealloc(ptr,nelems*elemsiz)`.
*
* This is roughly the same as reallocarray() function that OpenBSD
* etc. provides, but also interacts with our GC.
*
* @param[in] ptr A valid pointer to a storage instance that was
* previously returned from either:
* - ruby_xmalloc(),
* - ruby_xmalloc2(),
* - ruby_xcalloc(),
* - ruby_xrealloc(), or
* - ruby_xrealloc2().
* @param[in] newelems Requested new number of elements.
* @param[in] newsiz Requested new size of each element.
* @exception rb_eNoMemError No space left for allocation.
* @exception rb_eArgError `newelems` * `newsiz` would overflow.
* @return A valid pointer to a (possibly newly allocated) storage
* instance; which has at least `newelems` * `newsiz` bytes width,
* with appropriate alignment detected by the underlying realloc()
* routine.
* @pre The passed pointer must point to a valid live storage instance.
* It is a failure to pass an already freed pointer.
* @post In case the function returns the passed pointer as-is, the
* storage instance that the pointer holds is either grown or
* shrunken to have at least `newelems` * `newsiz` bytes.
* Otherwise a valid pointer to a newly allocated storage instance
* is returned. In this case `ptr` is invalidated as if it was
* passed to ruby_xfree().
* @note It doesn't return NULL.
* @warning Unlike some realloc() implementations, passing zero to either
* `newelems` or `elemsiz` are not the same as calling
* ruby_xfree(), because this function never returns NULL.
* Something meaningful still returns then.
* @warning It is a failure not to check the return value. Do not assume
* anything on it. It could be either identical to, or distinct
* form the passed argument.
* @warning Do not assume anything on the alignment of the return value.
* There is no guarantee that it inherits the passed argument's
* one.
* @warning The return value shall be invalidated exactly once by either
* ruby_xfree(), ruby_xrealloc(), or ruby_xrealloc2(). It is a
* failure to pass it to system free(), because the system and Ruby
* might or might not share the same malloc() implementation.
*/
void *ruby_xrealloc2(void *ptr, size_t newelems, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newelems * newsiz))
;
/**
* Deallocates a storage instance.
*
* @param[out] ptr Either
* - NULL, or
* - a valid pointer previously returned from one of:
* - ruby_xmalloc(),
* - ruby_xmalloc2(),
* - ruby_xcalloc(),
* - ruby_xrealloc(), or
* - ruby_xrealloc2().
* @pre The passed pointer must point to a valid live storage instance.
* It is a failure to pass an already freed pointer.
* @post The storage instance pointed by the passed pointer gets
* invalidated; it is no longer addressable.
* @warning Every single storage instance that was previously allocated by
* either ruby_xmalloc(), ruby_xmalloc2(), ruby_xcalloc(),
* ruby_xrealloc(), or ruby_xrealloc2() shall be invalidated
* exactly once by either passing it to ruby_xfree(), or passing
* it to either ruby_xrealloc(), ruby_xrealloc2() then check the
* return value for invalidation.
* @warning Do not pass anything other than pointers described above. For
* instance pointers returned from malloc() or mmap() shall not be
* passed to this function, because the underlying memory
* management mechanism could differ.
* @warning Do not pass any invalid pointers to this function e.g. by
* calling it twice with a same argument.
*/
void ruby_xfree(void *ptr)
RBIMPL_ATTR_NOEXCEPT(free(ptr))
;
#if USE_GC_MALLOC_OBJ_INFO_DETAILS
# define ruby_xmalloc(s1) ruby_xmalloc_with_location(s1, __FILE__, __LINE__)
# define ruby_xmalloc2(s1, s2) ruby_xmalloc2_with_location(s1, s2, __FILE__, __LINE__)
# define ruby_xcalloc(s1, s2) ruby_xcalloc_with_location(s1, s2, __FILE__, __LINE__)
# define ruby_xrealloc(ptr, s1) ruby_xrealloc_with_location(ptr, s1, __FILE__, __LINE__)
# define ruby_xrealloc2(ptr, s1, s2) ruby_xrealloc2_with_location(ptr, s1, s2, __FILE__, __LINE__)
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1))
void *ruby_xmalloc_body(size_t size)
RBIMPL_ATTR_NOEXCEPT(malloc(size))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
void *ruby_xmalloc2_body(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(malloc(nelems * elemsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
void *ruby_xcalloc_body(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(calloc(nelems, elemsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2))
void *ruby_xrealloc_body(void *ptr, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newsiz))
;
RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2,3))
void *ruby_xrealloc2_body(void *ptr, size_t newelems, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newelems * newsiz))
;
RUBY_EXTERN const char *ruby_malloc_info_file;
RUBY_EXTERN int ruby_malloc_info_line;
static inline void *
ruby_xmalloc_with_location(size_t s, const char *file, int line)
{
void *ptr;
ruby_malloc_info_file = file;
ruby_malloc_info_line = line;
ptr = ruby_xmalloc_body(s);
ruby_malloc_info_file = NULL;
return ptr;
}
static inline void *
ruby_xmalloc2_with_location(size_t s1, size_t s2, const char *file, int line)
{
void *ptr;
ruby_malloc_info_file = file;
ruby_malloc_info_line = line;
ptr = ruby_xmalloc2_body(s1, s2);
ruby_malloc_info_file = NULL;
return ptr;
}
static inline void *
ruby_xcalloc_with_location(size_t s1, size_t s2, const char *file, int line)
{
void *ptr;
ruby_malloc_info_file = file;
ruby_malloc_info_line = line;
ptr = ruby_xcalloc_body(s1, s2);
ruby_malloc_info_file = NULL;
return ptr;
}
static inline void *
ruby_xrealloc_with_location(void *ptr, size_t s, const char *file, int line)
{
void *rptr;
ruby_malloc_info_file = file;
ruby_malloc_info_line = line;
rptr = ruby_xrealloc_body(ptr, s);
ruby_malloc_info_file = NULL;
return rptr;
}
static inline void *
ruby_xrealloc2_with_location(void *ptr, size_t s1, size_t s2, const char *file, int line)
{
void *rptr;
ruby_malloc_info_file = file;
ruby_malloc_info_line = line;
rptr = ruby_xrealloc2_body(ptr, s1, s2);
ruby_malloc_info_file = NULL;
return rptr;
}
#endif
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_XMALLOC_H */
include/ruby/internal/arithmetic.h 0000644 00000004105 15040330606 0013263 0 ustar 00 #ifndef RBIMPL_ARITHMETIC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Conversion between C's arithmetic types and Ruby's numeric
* types.
*/
#include "ruby/internal/arithmetic/char.h"
#include "ruby/internal/arithmetic/double.h"
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/gid_t.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/intptr_t.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/internal/arithmetic/mode_t.h"
#include "ruby/internal/arithmetic/off_t.h"
#include "ruby/internal/arithmetic/pid_t.h"
#include "ruby/internal/arithmetic/short.h"
#include "ruby/internal/arithmetic/size_t.h"
#include "ruby/internal/arithmetic/st_data_t.h"
#include "ruby/internal/arithmetic/uid_t.h"
#endif /* RBIMPL_ARITHMETIC_H */
include/ruby/internal/newobj.h 0000644 00000017230 15040330606 0012421 0 ustar 00 #ifndef RBIMPL_NEWOBJ_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_NEWOBJ_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #NEWOBJ.
*/
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
/**
* Declares, allocates, then assigns a new object to the given variable.
*
* @param obj Variable name.
* @param type Variable type.
* @exception rb_eNoMemError No space left.
* @return An allocated object, not initialised.
* @note Modern programs tend to use #NEWOBJ_OF instead.
*
* @internal
*
* :FIXME: Should we deprecate it?
*/
#define RB_NEWOBJ(obj,type) type *(obj) = RBIMPL_CAST((type *)rb_newobj())
/**
* Identical to #RB_NEWOBJ, except it also accepts the allocating object's
* class and flags.
*
* @param obj Variable name.
* @param type Variable type.
* @param klass Object's class.
* @param flags Object's flags.
* @exception rb_eNoMemError No space left.
* @return An allocated object, filled with the arguments.
*/
#define RB_NEWOBJ_OF(obj,type,klass,flags) type *(obj) = RBIMPL_CAST((type *)rb_newobj_of(klass, flags))
#define NEWOBJ RB_NEWOBJ /**< @old{RB_NEWOBJ} */
#define NEWOBJ_OF RB_NEWOBJ_OF /**< @old{RB_NEWOBJ_OF} */
#define OBJSETUP rb_obj_setup /**< @old{rb_obj_setup} */
#define CLONESETUP rb_clone_setup /**< @old{rb_clone_setup} */
#define DUPSETUP rb_dup_setup /**< @old{rb_dup_setup} */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the implementation detail of #RB_NEWOBJ.
*
* @exception rb_eNoMemError No space left.
* @return An allocated object, not initialised.
*/
VALUE rb_newobj(void);
/**
* This is the implementation detail of #RB_NEWOBJ_OF.
*
* @param klass Object's class.
* @param flags Object's flags.
* @exception rb_eNoMemError No space left.
* @return An allocated object, filled with the arguments.
*/
VALUE rb_newobj_of(VALUE klass, VALUE flags);
/**
* Fills common fields in the object.
*
* @note Prefer rb_newobj_of() to this function.
* @param[in,out] obj A Ruby object to be set up.
* @param[in] klass `obj` will belong to this class.
* @param[in] type One of ::ruby_value_type.
* @return The passed object.
*
* @internal
*
* Historically, authors of Ruby has described the `type` argument as "one of
* ::ruby_value_type". In reality it accepts either ::ruby_value_type,
* ::ruby_fl_type, or any combinations of the two. For instance
* `RUBY_T_STRING | RUBY_FL_FREEZE` is a valid value that this function takes,
* and means this is a frozen string.
*
* 3rd party extension libraries rarely need to allocate Strings this way.
* They normally only concern ::RUBY_T_DATA. This argument is mainly used for
* specifying flags, @shyouhei suspects.
*/
VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
/**
* Queries the class of an object. This is not always identical to
* `RBASIC_CLASS(obj)`. It searches for the nearest ancestor skipping
* singleton classes or included modules.
*
* @param[in] obj Object in question.
* @return The object's class, in a normal sense.
*/
VALUE rb_obj_class(VALUE obj);
/**
* Clones a singleton class. An object can have its own singleton class. OK.
* Then what happens when a program clones such object? The singleton class
* that is attached to the source object must also be cloned. Otherwise a
* singleton object gets shared with two objects, which breaks "singleton"-ness
* of such class.
*
* This is basically an implementation detail of rb_clone_setup(). People
* need not be aware of this working behind-the-scene.
*
* @param[in] obj The object that has its own singleton class.
* @return Cloned singleton class.
*/
VALUE rb_singleton_class_clone(VALUE obj);
/**
* Attaches a singleton class to its corresponding object.
*
* This is basically an implementation detail of rb_clone_setup(). People
* need not be aware of this working behind-the-scene.
*
* @param[in] klass The singleton class.
* @param[out] obj The object to attach a class.
* @pre The passed two objects must agree with each other that `klass`
* becomes a singleton class of `obj`.
* @post `klass` becomes the singleton class of `obj`.
*/
void rb_singleton_class_attached(VALUE klass, VALUE obj);
/**
* Copies the list of instance variables. 3rd parties need not know, but there
* are several ways to store an object's instance variables, depending on its
* internal structure. This function makes sense when either of the passed
* objects are using so-called "generic" backend storage. This distinction is
* purely an implementation detail of rb_clone_setup(). People need not be
* aware of this working behind-the-scenes.
*
* @param[out] clone The destination object.
* @param[in] obj The source object.
*/
void rb_copy_generic_ivar(VALUE clone, VALUE obj);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#clone works."))
/**
* @deprecated Not sure exactly when but at some time, the implementation of
* `Object#clone` stopped using this function. It remained
* untouched for a while, and then @shyouhei realised that they
* are no longer doing the same thing. It seems nobody seriously
* uses this function any longer. Let's just abandon it.
*
* @param[out] clone The destination object.
* @param[in] obj The source object.
*/
static inline void
rb_clone_setup(VALUE clone, VALUE obj)
{
return;
}
RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#dup works."))
/**
* @deprecated Not sure exactly when but at some time, the implementation of
* `Object#dup` stopped using this function. It remained
* untouched for a while, and then @shyouhei realised that they
* are no longer the same thing. It seems nobody seriously uses
* this function any longer. Let's just abandon it.
*
* @param[out] dup The destination object.
* @param[in] obj The source object.
*/
static inline void
rb_dup_setup(VALUE dup, VALUE obj)
{
return;
}
#endif /* RBIMPL_NEWOBJ_H */
include/ruby/internal/variable.h 0000644 00000027473 15040330606 0012734 0 ustar 00 #ifndef RBIMPL_VARIABLE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VARIABLE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Declares rb_define_variable().
*/
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Type that represents a global variable getter function.
*
* @param[in] id The variable name.
* @param[in,out] data Where the value is stored.
* @return The value that shall be visible from Ruby.
*/
typedef VALUE rb_gvar_getter_t(ID id, VALUE *data);
/**
* Type that represents a global variable setter function.
*
* @param[in] val The value to set.
* @param[in] id The variable name.
* @param[in,out] data Where the value is to be stored.
*/
typedef void rb_gvar_setter_t(VALUE val, ID id, VALUE *data);
/**
* Type that represents a global variable marker function.
*
* @param[in] var Where the value is to be stored.
*/
typedef void rb_gvar_marker_t(VALUE *var);
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_getter_t rb_gvar_undef_getter;
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_setter_t rb_gvar_undef_setter;
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_marker_t rb_gvar_undef_marker;
/**
* This is the getter function that backs global variables defined from a ruby
* script. Extension libraries can use this if its global variable needs no
* custom logic.
*/
rb_gvar_getter_t rb_gvar_val_getter;
/**
* This is the setter function that backs global variables defined from a ruby
* script. Extension libraries can use this if its global variable needs no
* custom logic.
*/
rb_gvar_setter_t rb_gvar_val_setter;
/**
* This is the setter function that backs global variables defined from a ruby
* script. Extension libraries can use this if its global variable needs no
* custom logic.
*/
rb_gvar_marker_t rb_gvar_val_marker;
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_getter_t rb_gvar_var_getter;
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_setter_t rb_gvar_var_setter;
/**
* @deprecated
*
* This function has no actual usage (than in ruby itself). Please ignore. It
* was a bad idea to expose this function to 3rd parties, but we can no longer
* delete it.
*/
rb_gvar_marker_t rb_gvar_var_marker;
RBIMPL_ATTR_NORETURN()
/**
* This function just raises ::rb_eNameError. Handy when you want to prohibit
* a global variable from being squashed by someone.
*/
rb_gvar_setter_t rb_gvar_readonly_setter;
RBIMPL_ATTR_NONNULL(())
/**
* "Shares" a global variable between Ruby and C. Normally a Ruby-level global
* variable is stored somewhere deep inside of the interpreter's execution
* context, but this way you can explicitly specify its storage.
*
* ```CXX
* static VALUE foo;
*
* extern "C" void
* init_Foo(void)
* {
* foo = rb_eval_string("...");
* rb_define_variable("$foo", &foo);
* }
* ```
*
* In the above example a Ruby global variable named `$foo` is stored in a C
* global variable named `foo`.
*
* @param[in] name Variable (Ruby side).
* @param[in] var Variable (C side).
* @post Ruby level global variable named `name` is defined if absent,
* and its storage is set to `var`.
*/
void rb_define_variable(const char *name, VALUE *var);
RBIMPL_ATTR_NONNULL((1))
/**
* Defines a global variable that is purely function-backended. By using this
* API a programmer can define a global variable that dynamically changes from
* time to time.
*
* @param[in] name Variable name, in C's string.
* @param[in] getter A getter function.
* @param[in] setter A setter function.
* @post Ruby level global variable named `name` is defined if absent.
*
* @internal
*
* @shyouhei doesn't know if this is an Easter egg or an official feature, but
* you can pass 0 to the third argument (setter). That effectively nullifies
* any efforts to write to the defining global variable.
*/
void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);
RBIMPL_ATTR_NONNULL((1))
/**
* Identical to rb_define_virtual_variable(), but can also specify a storage.
* A programmer can use the storage for e.g. memoisation, storing intermediate
* computation result, etc.
*
* Also you can pass 0 to this function, unlike other variants:
*
* - When getter is 0 ::rb_gvar_var_getter is used instead.
* - When setter is 0 ::rb_gvar_var_setter is used instead.
* - When data is 0, you must specify a non-zero setter function. Otherwise
* ::rb_gvar_var_setter tries to write to `*NULL`, and just causes SEGV.
*
* @param[in] name Variable name, in C's string.
* @param[in] var Variable storage.
* @param[in] getter A getter function.
* @param[in] setter A setter function.
* @post Ruby level global variable named `name` is defined if absent.
*/
void rb_define_hooked_variable(const char *name, VALUE *var, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_define_variable(), except it does not allow Ruby programs to
* assign values to such global variable. C codes can still set values at
* will. This could be handy for you when implementing an `errno`-like
* experience, where a method updates a read-only global variable as a side-
* effect.
*
* @param[in] name Variable (Ruby side).
* @param[in] var Variable (C side).
* @post Ruby level global variable named `name` is defined if absent,
* and its storage is set to `var`.
*/
void rb_define_readonly_variable(const char *name, const VALUE *var);
RBIMPL_ATTR_NONNULL(())
/**
* Defines a Ruby level constant under a namespace.
*
* @param[out] klass Namespace for the constant to reside.
* @param[in] name Name of the constant.
* @param[in] val Value of the constant.
* @exception rb_eTypeError `klass` is not a kind of ::rb_cModule.
* @exception rb_eFrozenError `klass` is frozen.
* @post Ruby level constant `klass::name` is defined to be `val`.
* @note This API does not stop you from defining a constant that is
* unable to reach from ruby (like for instance passing
* non-capital letter to `name`).
* @note This API does not stop you from overwriting a constant that
* already exist.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_define_const(VALUE klass, const char *name, VALUE val);
RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_define_const(), except it defines that of "global",
* i.e. toplevel constant.
*
* @param[in] name Name of the constant.
* @param[in] val Value of the constant.
* @exception rb_eFrozenError ::rb_cObject is frozen.
* @post Ruby level constant \::name is defined to be `val`.
* @note This API does not stop you from defining a constant that is
* unable to reach from ruby (like for instance passing
* non-capital letter to `name`).
* @note This API does not stop you from overwriting a constant that
* already exist.
*/
void rb_define_global_const(const char *name, VALUE val);
RBIMPL_ATTR_NONNULL(())
/**
* Asserts that the given constant is deprecated. Attempt to refer such
* constant will produce a warning.
*
* @param[in] mod Namespace of the target constant.
* @param[in] name Name of the constant.
* @exception rb_eNameError No such constant.
* @exception rb_eFrozenError `mod` is frozen.
* @post `name` under `mod` is deprecated.
*/
void rb_deprecate_constant(VALUE mod, const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* Assigns to a global variable.
*
* @param[in] name Target global variable.
* @param[in] val Value to assign.
* @return Passed value.
* @post Ruby level global variable named `name` is defined if absent,
* whose value is set to `val`.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with
* `set_trace_func`.
*/
VALUE rb_gv_set(const char *name, VALUE val);
RBIMPL_ATTR_NONNULL(())
/**
* Obtains a global variable.
*
* @param[in] name Global variable to query.
* @retval RUBY_Qnil The global variable does not exist.
* @retval otherwise The value assigned to the global variable.
*
* @internal
*
* Unlike rb_gv_set(), there is no way to trace this function.
*/
VALUE rb_gv_get(const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* Obtains an instance variable.
*
* @param[in] obj Target object.
* @param[in] name Target instance variable to query.
* @exception rb_eEncodingError `name` is corrupt (contains Hanzi etc.).
* @retval RUBY_nil No such instance variable.
* @retval otherwise The value assigned to the instance variable.
*/
VALUE rb_iv_get(VALUE obj, const char *name);
RBIMPL_ATTR_NONNULL(())
/**
* Assigns to an instance variable.
*
* @param[out] obj Target object.
* @param[in] name Target instance variable.
* @param[in] val Value to assign.
* @exception rb_eFrozenError Can't modify `obj`.
* @exception rb_eArgError `obj` has too many instance variables.
* @return Passed value.
* @post An instance variable named `name` is defined if absent on
* `obj`, whose value is set to `val`.
*
* @internal
*
* This function does not stop you form creating an ASCII-incompatible instance
* variable, but there is no way to get one because rb_iv_get raises exceptions
* for such things. This design seems broken... But no idea why.
*/
VALUE rb_iv_set(VALUE obj, const char *name, VALUE val);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_VARIABLE_H */
include/ruby/internal/dllexport.h 0000644 00000010070 15040330606 0013145 0 ustar 00 #ifndef RBIMPL_DLLEXPORT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_DLLEXPORT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Tweaking visibility of C variables/functions.
*/
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_is.h"
/**
* Declaration of externally visible global variables. Here "externally" means
* they should be visible from extension libraries. Depending on operating
* systems (dynamic linkers, to be precise), global variables inside of a DLL
* may or may not be visible form outside of that DLL by default. This
* declaration manually tweaks that default and ensures the declared variable
* be truly globally visible.
*
* ```CXX
* extern VALUE foo; // hidden on some OS
* RUBY_EXTERN VALUE foo; // ensure visible
* ```
*/
#undef RUBY_EXTERN
#if defined(MJIT_HEADER) && defined(_WIN32)
# define RUBY_EXTERN extern __declspec(dllimport)
#elif defined(RUBY_EXPORT)
# define RUBY_EXTERN extern
#elif defined(_WIN32)
# define RUBY_EXTERN extern __declspec(dllimport)
#else
# define RUBY_EXTERN extern
#endif
#ifndef RUBY_SYMBOL_EXPORT_BEGIN
# define RUBY_SYMBOL_EXPORT_BEGIN /* begin */
#endif
#ifndef RUBY_SYMBOL_EXPORT_END
# define RUBY_SYMBOL_EXPORT_END /* end */
#endif
#ifndef RUBY_FUNC_EXPORTED
# define RUBY_FUNC_EXPORTED /* void */
#endif
/**
* @cond INTERNAL_MACRO
*
* These MJIT related macros are placed here because translate_mjit_header can
* need them. Extension libraries should not touch.
*/
/* These macros are used for functions which are exported only for MJIT
and NOT ensured to be exported in future versions. */
#if ! defined(MJIT_HEADER)
# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
#elif ! RBIMPL_COMPILER_IS(MSVC)
# define MJIT_FUNC_EXPORTED RUBY_FUNC_EXPORTED
#else
# define MJIT_FUNC_EXPORTED static
#endif
#define MJIT_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
#define MJIT_SYMBOL_EXPORT_END RUBY_SYMBOL_EXPORT_END
/* On mswin, MJIT header transformation can't be used since cl.exe can't output
preprocessed output preserving macros. So this `MJIT_STATIC` is needed
to force non-static function to static on MJIT header to avoid symbol conflict. */
#ifdef MJIT_HEADER
# define MJIT_STATIC static
#else
# define MJIT_STATIC
#endif
/** @endcond */
/** Shortcut macro equivalent to `RUBY_SYMBOL_EXPORT_BEGIN extern "C" {`.
* \@shyouhei finds it handy. */
#if defined(__DOXYGEN__)
# define RBIMPL_SYMBOL_EXPORT_BEGIN() /* void */
#elif defined(__cplusplus)
# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN extern "C" {
#else
# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN
#endif
/** Counterpart of #RBIMPL_SYMBOL_EXPORT_BEGIN */
#if defined(__DOXYGEN__)
# define RBIMPL_SYMBOL_EXPORT_END() /* void */
#elif defined(__cplusplus)
# define RBIMPL_SYMBOL_EXPORT_END() } RUBY_SYMBOL_EXPORT_END
#else
# define RBIMPL_SYMBOL_EXPORT_END() RUBY_SYMBOL_EXPORT_END
#endif
#endif /* RBIMPL_DLLEXPORT_H */
include/ruby/internal/abi.h 0000644 00000003023 15040330606 0011663 0 ustar 00 #ifndef RUBY_ABI_H
#define RUBY_ABI_H
#ifdef RUBY_ABI_VERSION /* should match the definition in config.h */
/* This number represents Ruby's ABI version.
*
* In development Ruby, it should be bumped every time an ABI incompatible
* change is introduced. This will force other developers to rebuild extension
* gems.
*
* The following cases are considered as ABI incompatible changes:
* - Changing any data structures.
* - Changing macros or inline functions causing a change in behavior.
* - Deprecating or removing function declarations.
*
* The following cases are NOT considered as ABI incompatible changes:
* - Any changes that does not involve the header files in the `include`
* directory.
* - Adding macros, inline functions, or function declarations.
* - Backwards compatible refactors.
* - Editing comments.
*
* In released versions of Ruby, this number is not defined since teeny
* versions of Ruby should guarantee ABI compatibility.
*/
#define RUBY_ABI_VERSION 3
/* Windows does not support weak symbols so ruby_abi_version will not exist
* in the shared library. */
#if defined(HAVE_FUNC_WEAK) && !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define RUBY_DLN_CHECK_ABI
#endif
#endif /* RUBY_ABI_VERSION */
#ifdef RUBY_DLN_CHECK_ABI
# ifdef __cplusplus
extern "C" {
# endif
RUBY_FUNC_EXPORTED unsigned long long __attribute__((weak))
ruby_abi_version(void)
{
# ifdef RUBY_ABI_VERSION
return RUBY_ABI_VERSION;
# else
return 0;
# endif
}
# ifdef __cplusplus
}
# endif
#endif
#endif
include/ruby/internal/rgengc.h 0000644 00000032310 15040330606 0012376 0 ustar 00 #ifndef RBIMPL_RGENGC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RGENGC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief RGENGC write-barrier APIs.
* @see Sasada, K., "Gradual write-barrier insertion into a Ruby
* interpreter", in proceedings of the 2019 ACM SIGPLAN
* International Symposium on Memory Management (ISMM 2019), pp
* 115-121, 2019. https://doi.org/10.1145/3315573.3329986
*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#undef USE_RGENGC
#define USE_RGENGC 1
/**
* @private
*
* This is a compile-time flag to enable/disable incremental GC feature. It
* has to be set at the time ruby itself compiles. Makes no sense for 3rd
* parties. It is safe for them to set this though; that just doesn't change
* anything.
*/
#ifndef USE_RINCGC
# define USE_RINCGC 1
#endif
/**
* @deprecated This macro seems broken. Setting this to anything other than
* zero just doesn't compile. We need to KonMari.
*/
#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
# define USE_RGENGC_LOGGING_WB_UNPROTECT 0
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RArray. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_ARRAY
# define RGENGC_WB_PROTECTED_ARRAY 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RHash. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_HASH
# define RGENGC_WB_PROTECTED_HASH 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RStruct. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_STRUCT
# define RGENGC_WB_PROTECTED_STRUCT 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RString. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_STRING
# define RGENGC_WB_PROTECTED_STRING 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RObject. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_OBJECT
# define RGENGC_WB_PROTECTED_OBJECT 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RRegexp. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_REGEXP
# define RGENGC_WB_PROTECTED_REGEXP 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RClass. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_CLASS
# define RGENGC_WB_PROTECTED_CLASS 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RFloat. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_FLOAT
# define RGENGC_WB_PROTECTED_FLOAT 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RComplex. It has to be set at the time ruby itself compiles.
* Makes no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_COMPLEX
# define RGENGC_WB_PROTECTED_COMPLEX 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RRational. It has to be set at the time ruby itself compiles.
* Makes no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_RATIONAL
# define RGENGC_WB_PROTECTED_RATIONAL 1
#endif
/**
* @private
*
* This is a compile-time flag to enable/disable write barrier for
* struct ::RBignum. It has to be set at the time ruby itself compiles. Makes
* no sense for 3rd parties.
*/
#ifndef RGENGC_WB_PROTECTED_BIGNUM
# define RGENGC_WB_PROTECTED_BIGNUM 1
#endif
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* @shyouhei doesn't think anybody uses this right now.
*/
#ifndef RGENGC_WB_PROTECTED_NODE_CREF
# define RGENGC_WB_PROTECTED_NODE_CREF 1
#endif
/**
* @defgroup rgengc Write barrier (WB) interfaces:
*
* @note The following core interfaces can be changed in the future. Please
* catch up if you want to insert WB into C-extensions correctly.
*
* @{
*/
/**
* Declaration of a "back" pointer. This is a write barrier for new reference
* from "old" generation to "young" generation. It writes `young` into
* `*slot`, which is a pointer inside of `old`.
*
* @param[in] old An old object.
* @param[in] slot A pointer inside of `old`.
* @param[out] young A young object.
*/
#define RB_OBJ_WRITE(old, slot, young) \
RBIMPL_CAST(rb_obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))
/**
* Identical to #RB_OBJ_WRITE(), except it doesn't write any values, but only a
* WB declaration. `oldv` is replaced value with `b` (not used in current
* Ruby).
*
* @param[in] old An old object.
* @param[in] oldv An object previously stored inside of `old`.
* @param[out] young A young object.
*/
#define RB_OBJ_WRITTEN(old, oldv, young) \
RBIMPL_CAST(rb_obj_written((VALUE)(old), (VALUE)(oldv), (VALUE)(young), __FILE__, __LINE__))
/** @} */
#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW /**< @old{RB_OBJ_PROMOTED_RAW} */
#define OBJ_PROMOTED RB_OBJ_PROMOTED /**< @old{RB_OBJ_PROMOTED} */
#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT /**< @old{RB_OBJ_WB_UNPROTECT} */
/**
* Asserts that the passed object is not fenced by write barriers. Objects of
* such property do not contribute to generational GCs. They are scanned
* always.
*
* @param[out] x An object that would not be protected by the barrier.
*/
#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)
/**
* Identical to #RB_OBJ_WB_UNPROTECT(), except it can also assert that the
* given object is of given type.
*
* @param[in] type One of `ARRAY`, `STRING`, etc.
* @param[out] obj An object of `type` that would not be protected.
*
* @internal
*
* @shyouhei doesn't understand why this has to be visible from extensions.
*/
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
(RGENGC_WB_PROTECTED_##type ? OBJ_WB_UNPROTECT(obj) : obj)
/**
* @private
*
* This is an implementation detail of rb_obj_wb_unprotect(). People don't use
* it directly.
*/
#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging
/** @cond INTERNAL_MACRO */
#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
#define RB_OBJ_PROMOTED RB_OBJ_PROMOTED
/** @endcond */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* This is the implementation of #RB_OBJ_WRITE(). People don't use it
* directly.
*
* @param[in] old An object that points to `young`.
* @param[out] young An object that is referenced from `old`.
*/
void rb_gc_writebarrier(VALUE old, VALUE young);
/**
* This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
* directly.
*
* @param[out] obj An object that does not participate in WB.
*/
void rb_gc_writebarrier_unprotect(VALUE obj);
#if USE_RGENGC_LOGGING_WB_UNPROTECT
/**
* @private
*
* This is the implementation of #RGENGC_LOGGING_WB_UNPROTECT(). People
* don't use it directly.
*
* @param[in] objptr Don't know why this is a pointer to void but in
* reality this is a pointer to an object that is about
* to be un-protected.
* @param[in] filename Pass C's `__FILE__` here.
* @param[in] line Pass C's `__LINE__` here.
*/
void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
#endif
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* This is the implementation of #RB_OBJ_PROMOTED(). People don't use it
* directly.
*
* @param[in] obj An object to query.
* @retval true The object is "promoted".
* @retval false The object is young. Have not experienced GC at all.
*/
static inline bool
RB_OBJ_PROMOTED_RAW(VALUE obj)
{
RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
return RB_FL_ANY_RAW(obj, RUBY_FL_PROMOTED);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Tests if the object is "promoted" -- that is, whether the object experienced
* one or more GC marks.
*
* @param[in] obj An object to query.
* @retval true The object is "promoted".
* @retval false The object is young. Have not experienced GC at all.
* @note Hello, is anyone actively calling this function? @shyouhei have
* never seen any actual usages outside of the GC implementation
* itself.
*/
static inline bool
RB_OBJ_PROMOTED(VALUE obj)
{
if (! RB_FL_ABLE(obj)) {
return false;
}
else {
return RB_OBJ_PROMOTED_RAW(obj);
}
}
/**
* This is the implementation of #RB_OBJ_WB_UNPROTECT(). People don't use it
* directly.
*
* @param[out] x An object that does not participate in WB.
* @param[in] filename C's `__FILE__` of the caller function.
* @param[in] line C's `__LINE__` of the caller function.
* @return x
*/
static inline VALUE
rb_obj_wb_unprotect(
VALUE x,
RBIMPL_ATTR_MAYBE_UNUSED()
const char *filename,
RBIMPL_ATTR_MAYBE_UNUSED()
int line)
{
#if USE_RGENGC_LOGGING_WB_UNPROTECT
RGENGC_LOGGING_WB_UNPROTECT(RBIMPL_CAST((void *)x), filename, line);
#endif
rb_gc_writebarrier_unprotect(x);
return x;
}
/**
* @private
*
* This is the implementation of #RB_OBJ_WRITTEN(). People don't use it
* directly.
*
* @param[in] a An old object.
* @param[in] oldv An object previously stored inside of `old`.
* @param[out] b A young object.
* @param[in] filename C's `__FILE__` of the caller function.
* @param[in] line C's `__LINE__` of the caller function.
* @return a
*/
static inline VALUE
rb_obj_written(
VALUE a,
RBIMPL_ATTR_MAYBE_UNUSED()
VALUE oldv,
VALUE b,
RBIMPL_ATTR_MAYBE_UNUSED()
const char *filename,
RBIMPL_ATTR_MAYBE_UNUSED()
int line)
{
#if USE_RGENGC_LOGGING_WB_UNPROTECT
RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
#endif
if (!RB_SPECIAL_CONST_P(b)) {
rb_gc_writebarrier(a, b);
}
return a;
}
/**
* @private
*
* This is the implementation of #RB_OBJ_WRITE(). People don't use it
* directly.
*
* @param[in] a An old object.
* @param[in] slot A pointer inside of `old`.
* @param[out] b A young object.
* @param[in] filename C's `__FILE__` of the caller function.
* @param[in] line C's `__LINE__` of the caller function.
* @return a
*/
static inline VALUE
rb_obj_write(
VALUE a, VALUE *slot, VALUE b,
RBIMPL_ATTR_MAYBE_UNUSED()
const char *filename,
RBIMPL_ATTR_MAYBE_UNUSED()
int line)
{
#ifdef RGENGC_LOGGING_WRITE
RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
#endif
*slot = b;
rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
return a;
}
#endif /* RBIMPL_RGENGC_H */
include/ruby/internal/attr/deprecated.h 0000644 00000006474 15040330606 0014217 0 ustar 00 #ifndef RBIMPL_ATTR_DEPRECATED_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_DEPRECATED_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_DEPRECATED.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
#include "ruby/internal/has/extension.h"
/** Wraps (or simulates) `[[deprecated]]` */
#if defined(__COVERITY__)
/* Coverity Scan emulates gcc but seems not to support this attribute correctly */
# define RBIMPL_ATTR_DEPRECATED(msg)
#elif RBIMPL_HAS_EXTENSION(attribute_deprecated_with_message)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(GCC, 10, 1, 0) && RBIMPL_COMPILER_BEFORE(GCC, 10, 3, 0)
# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95302 */
# define RBIMPL_ATTR_DEPRECATED(msg) /* disable until they fix this bug */
#elif RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))
#elif RBIMPL_HAS_ATTRIBUTE(deprecated) /* but not with message. */
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__))
#elif RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated msg)
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated)
#elif RBIMPL_HAS_CPP_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]
#elif RBIMPL_HAS_C_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]
#else
# define RBIMPL_ATTR_DEPRECATED(msg) /* void */
#endif
/** This is when a function is used internally (for backwards compatibility
* etc.), but extension libraries must consider it deprecated. */
#if defined(RUBY_EXPORT)
# define RBIMPL_ATTR_DEPRECATED_EXT(msg) /* void */
#else
# define RBIMPL_ATTR_DEPRECATED_EXT(msg) RBIMPL_ATTR_DEPRECATED(msg)
#endif
#endif /* RBIMPL_ATTR_DEPRECATED_H */
include/ruby/internal/attr/noreturn.h 0000644 00000004131 15040330606 0013757 0 ustar 00 #ifndef RBIMPL_ATTR_NORETURN_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NORETURN_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NORETURN.
*/
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
/** Wraps (or simulates) `[[noreturn]]` */
#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() __declspec(noreturn)
#elif RBIMPL_HAS_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() __attribute__((__noreturn__))
#elif RBIMPL_HAS_CPP_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() [[noreturn]]
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112)
# define RBIMPL_ATTR_NORETURN() _Noreturn
#elif defined(_Noreturn)
# /* glibc <sys/cdefs.h> has this macro. */
# define RBIMPL_ATTR_NORETURN() _Noreturn
#else
# define RBIMPL_ATTR_NORETURN() /* void */
#endif
#endif /* RBIMPL_ATTR_NORETURN_H */
include/ruby/internal/attr/diagnose_if.h 0000644 00000003723 15040330606 0014360 0 ustar 00 #ifndef RBIMPL_ATTR_DIAGNOSE_IF_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_DIAGNOSE_IF_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_DIAGNOSE_IF.
*/
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/warning_push.h"
/** Wraps (or simulates) `__attribute__((diagnose_if))` */
#if RBIMPL_COMPILER_BEFORE(Clang, 5, 0, 0)
# /* https://bugs.llvm.org/show_bug.cgi?id=34319 */
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */
#elif RBIMPL_HAS_ATTRIBUTE(diagnose_if)
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) \
RBIMPL_WARNING_PUSH() \
RBIMPL_WARNING_IGNORED(-Wgcc-compat) \
__attribute__((__diagnose_if__(_, __, ___))) \
RBIMPL_WARNING_POP()
#else
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */
#endif
#endif /* RBIMPL_ATTR_DIAGNOSE_IF_H */
include/ruby/internal/attr/error.h 0000644 00000003142 15040330606 0013235 0 ustar 00 #ifndef RBIMPL_ATTR_ERROR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ERROR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_ERROR.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((error))` */
#if RBIMPL_HAS_ATTRIBUTE(error)
# define RBIMPL_ATTR_ERROR(msg) __attribute__((__error__ msg))
#else
# define RBIMPL_ATTR_ERROR(msg) /* void */
#endif
#endif /* RBIMPL_ATTR_ERROR_H */
include/ruby/internal/attr/nodiscard.h 0000644 00000004252 15040330606 0014055 0 ustar 00 #ifndef RBIMPL_ATTR_NODISCARD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NODISCARD_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NODISCARD.
*/
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
/**
* Wraps (or simulates) `[[nodiscard]]`. In C++ (at least since C++20) a
* nodiscard attribute can have a message why the result shall not be ignored.
* However GCC attribute and SAL annotation cannot take them.
*/
#if RBIMPL_HAS_CPP_ATTRIBUTE(nodiscard)
# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
#elif RBIMPL_HAS_C_ATTRIBUTE(nodiscard)
# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
#elif RBIMPL_HAS_ATTRIBUTE(warn_unused_result)
# define RBIMPL_ATTR_NODISCARD() __attribute__((__warn_unused_result__))
#elif defined(_Check_return_)
# /* Take SAL definition. */
# define RBIMPL_ATTR_NODISCARD() _Check_return_
#else
# define RBIMPL_ATTR_NODISCARD() /* void */
#endif
#endif /* RBIMPL_ATTR_NODISCARD_H */
include/ruby/internal/attr/maybe_unused.h 0000644 00000003621 15040330606 0014566 0 ustar 00 #ifndef RBIMPL_ATTR_MAYBE_UNUSED_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_MAYBE_UNUSED_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_MAYBE_UNUSED.
*/
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
/** Wraps (or simulates) `[[maybe_unused]]` */
#if RBIMPL_HAS_CPP_ATTRIBUTE(maybe_unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
#elif RBIMPL_HAS_C_ATTRIBUTE(maybe_unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
#elif RBIMPL_HAS_ATTRIBUTE(unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() __attribute__((__unused__))
#else
# define RBIMPL_ATTR_MAYBE_UNUSED() /* void */
#endif
#endif /* RBIMPL_ATTR_MAYBE_UNUSED */
include/ruby/internal/attr/const.h 0000644 00000004237 15040330606 0013240 0 ustar 00 #ifndef RBIMPL_ATTR_CONST_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_CONST_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_CONST.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
/** Wraps (or simulates) `__attribute__((const))` */
#if RBIMPL_HAS_ATTRIBUTE(const)
# define RBIMPL_ATTR_CONST() __attribute__((__const__))
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
# /* If a function can be a const, that is also a noalias. */
# define RBIMPL_ATTR_CONST() __declspec(noalias)
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_CONST() _Pragma("no_side_effect")
#else
# define RBIMPL_ATTR_CONST() /* void */
#endif
/** Enables #RBIMPL_ATTR_CONST if and only if. ! #RUBY_DEBUG. */
#if !defined(RUBY_DEBUG) || !RUBY_DEBUG
# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() RBIMPL_ATTR_CONST()
#else
# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() /* void */
#endif
#endif /* RBIMPL_ATTR_CONST_H */
include/ruby/internal/attr/cold.h 0000644 00000003504 15040330606 0013027 0 ustar 00 #ifndef RBIMPL_ATTR_COLD_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_COLD_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_COLD.
*/
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((cold))` */
#if RBIMPL_COMPILER_IS(SunPro)
# /* Recent SunPro has __has_attribute, and is broken. */
# /* It reports it has attribute cold, reality isn't (warnings issued). */
# define RBIMPL_ATTR_COLD() /* void */
#elif RBIMPL_HAS_ATTRIBUTE(cold)
# define RBIMPL_ATTR_COLD() __attribute__((__cold__))
#else
# define RBIMPL_ATTR_COLD() /* void */
#endif
#endif /* RBIMPL_ATTR_COLD_H */
include/ruby/internal/attr/noalias.h 0000644 00000006734 15040330606 0013544 0 ustar 00 #ifndef RBIMPL_ATTR_NOALIAS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOALIAS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NOALIAS.
*
* ### Q&A ###
*
* - Q: There are seemingly similar attributes named #RBIMPL_ATTR_CONST,
* #RBIMPL_ATTR_PURE, and #RBIMPL_ATTR_NOALIAS. What are the difference?
*
* - A: Allowed operations are different.
*
* - #RBIMPL_ATTR_CONST ... Functions attributed by this are not allowed to
* read/write _any_ pointers at all (there are exceptional situations
* when reading a pointer is possible but forget that; they are too
* exceptional to be useful). Just remember that everything pointer-
* related are NG.
*
* - #RBIMPL_ATTR_PURE ... Functions attributed by this can read any
* nonvolatile pointers, but no writes are allowed at all. The ability
* to read _any_ nonvolatile pointers makes it possible to mark ::VALUE-
* taking functions as being pure, as long as they are read-only.
*
* - #RBIMPL_ATTR_NOALIAS ... Can both read/write, but only through
* pointers passed to the function as parameters. This is a typical
* situation when you create a C++ non-static member function which only
* concerns `this`. No global variables are allowed to read/write. So
* this is not a super-set of being pure. If you want to read something,
* that has to be passed to the function as a pointer. ::VALUE -taking
* functions thus cannot be attributed as such.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/declspec_attribute.h"
/** Wraps (or simulates) `__declspec((noalias))` */
#if RBIMPL_COMPILER_BEFORE(Clang, 12, 0, 0)
# /*
# * `::llvm::Attribute::ArgMemOnly` was buggy before. Maybe because nobody
# * actually seriously used it. It seems they somehow mitigated the situation
# * in LLVM 12. Still not found the exact changeset which fiexed the
# * attribute, though.
# *
# * :FIXME: others (armclang, xlclang, ...) can also be affected?
# */
# define RBIMPL_ATTR_NOALIAS() /* void */
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
# define RBIMPL_ATTR_NOALIAS() __declspec(noalias)
#else
# define RBIMPL_ATTR_NOALIAS() /* void */
#endif
#endif /* RBIMPL_ATTR_NOALIAS_H */
include/ruby/internal/attr/returns_nonnull.h 0000644 00000003431 15040330606 0015354 0 ustar 00 #ifndef RBIMPL_ATTR_RETURNS_NONNULL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_RETURNS_NONNULL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_RETURNS_NONNULL.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((returns_nonnull))` */
#if defined(_Ret_nonnull_)
# /* Take SAL definition. */
# define RBIMPL_ATTR_RETURNS_NONNULL() _Ret_nonnull_
#elif RBIMPL_HAS_ATTRIBUTE(returns_nonnull)
# define RBIMPL_ATTR_RETURNS_NONNULL() __attribute__((__returns_nonnull__))
#else
# define RBIMPL_ATTR_RETURNS_NONNULL() /* void */
#endif
#endif /* RBIMPL_ATTR_RETURNS_NONNULL_H */
include/ruby/internal/attr/nonnull.h 0000644 00000003336 15040330606 0013576 0 ustar 00 #ifndef RBIMPL_ATTR_NONNULL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NONNULL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NONNULL.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((nonnull))` */
#if RBIMPL_HAS_ATTRIBUTE(nonnull)
# define RBIMPL_ATTR_NONNULL(list) __attribute__((__nonnull__ list))
# define RBIMPL_NONNULL_ARG(arg) RBIMPL_ASSERT_NOTHING
#else
# define RBIMPL_ATTR_NONNULL(list) /* void */
# define RBIMPL_NONNULL_ARG(arg) RUBY_ASSERT(arg)
#endif
#endif /* RBIMPL_ATTR_NONNULL_H */
include/ruby/internal/attr/alloc_size.h 0000644 00000003220 15040330606 0014225 0 ustar 00 #ifndef RBIMPL_ATTR_ALLOC_SIZE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ALLOC_SIZE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_ALLOC_SIZE.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((alloc_size))` */
#if RBIMPL_HAS_ATTRIBUTE(alloc_size)
# define RBIMPL_ATTR_ALLOC_SIZE(tuple) __attribute__((__alloc_size__ tuple))
#else
# define RBIMPL_ATTR_ALLOC_SIZE(tuple) /* void */
#endif
#endif /* RBIMPL_ATTR_ALLOC_SIZE_H */
include/ruby/internal/attr/pure.h 0000644 00000003721 15040330606 0013062 0 ustar 00 #ifndef RBIMPL_ATTR_PURE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_PURE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_PURE.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/assert.h"
/** Wraps (or simulates) `__attribute__((pure))` */
#if RBIMPL_HAS_ATTRIBUTE(pure)
# define RBIMPL_ATTR_PURE() __attribute__((__pure__))
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_PURE() _Pragma("does_not_write_global_data")
#else
# define RBIMPL_ATTR_PURE() /* void */
#endif
/** Enables #RBIMPL_ATTR_PURE if and only if. ! #RUBY_DEBUG. */
#if !RUBY_DEBUG
# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_PURE()
#else
# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() /* void */
#endif
#endif /* RBIMPL_ATTR_PURE_H */
include/ruby/internal/attr/enum_extensibility.h 0000644 00000003275 15040330606 0016033 0 ustar 00 #ifndef RBIMPL_ATTR_ENUM_EXTENSIBILITY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ENUM_EXTENSIBILITY_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief #RBIMPL_ATTR_ENUM_EXTENSIBILITY.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((enum_extensibility))` */
#if RBIMPL_HAS_ATTRIBUTE(enum_extensibility)
# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) __attribute__((__enum_extensibility__(_)))
#else
# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) /* void */
#endif
#endif /* RBIMPL_ATTR_ENUM_EXTENSIBILITY_H */
include/ruby/internal/attr/format.h 0000644 00000003405 15040330606 0013376 0 ustar 00 #ifndef RBIMPL_ATTR_FORMAT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FORMAT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_FORMAT.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((format))` */
#if RBIMPL_HAS_ATTRIBUTE(format)
# define RBIMPL_ATTR_FORMAT(x, y, z) __attribute__((__format__(x, y, z)))
#else
# define RBIMPL_ATTR_FORMAT(x, y, z) /* void */
#endif
#if defined(__MINGW_PRINTF_FORMAT)
# define RBIMPL_PRINTF_FORMAT __MINGW_PRINTF_FORMAT
#else
# define RBIMPL_PRINTF_FORMAT __printf__
#endif
#endif /* RBIMPL_ATTR_FORMAT_H */
include/ruby/internal/attr/noinline.h 0000644 00000003400 15040330606 0013714 0 ustar 00 #ifndef RBIMPL_ATTR_NOINLINE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOINLINE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NOINLINE.
*/
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
/** Wraps (or simulates) `__declspec(noinline)` */
#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noinline)
# define RBIMPL_ATTR_NOINLINE() __declspec(noinline)
#elif RBIMPL_HAS_ATTRIBUTE(noinline)
# define RBIMPL_ATTR_NOINLINE() __attribute__((__noinline__))
#else
# define RBIMPL_ATTR_NOINLINE() /* void */
#endif
#endif /* RBIMPL_ATTR_NOINLINE_H */
include/ruby/internal/attr/noexcept.h 0000644 00000010256 15040330606 0013735 0 ustar 00 #ifndef RBIMPL_ATTR_NOEXCEPT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOEXCEPT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_NOEXCEPT.
*
* This isn't actually an attribute in C++ but who cares...
*
* Mainly due to aesthetic reasons, this one is rarely used in the project.
* But can be handy on occasions, especially when a function's noexcept-ness
* depends on its calling functions.
*
* ### Q&A ###
*
* - Q: Can a function that raises Ruby exceptions be attributed `noexcept`?
*
* - A: Yes. `noexcept` is about C++ exceptions, not Ruby's. They don't
* interface each other. You can safely attribute a function that raises
* Ruby exceptions as `noexcept`.
*
* - Q: How, then, can I assert that a function I wrote doesn't raise any Ruby
* exceptions?
*
* - A: `__attribute__((__leaf__))` is for that purpose. A function attributed
* as leaf can still throw C++ exceptions, but not Ruby's. Note however,
* that it's extremely difficult -- if not impossible -- to assert that a
* function doesn't raise any Ruby exceptions at all. Use of that
* attribute is not recommended; mere mortals can't properly use that by
* hand.
*
* - Q: Does it make sense to attribute an inline function `noexcept`?
*
* - A: I thought so before. But no, I don't think they are useful any longer.
*
* - When an inline function attributed `noexcept` actually doesn't throw
* any exceptions at all: these days I don't see any difference in
* generated assembly by adding/removing this attribute. C++ compilers
* get smarter and smarter. Today they can infer if it actually throws
* or not without any annotations by humans (correct me if I'm wrong).
*
* - When an inline function attributed `noexcepr` actually _does_ throw an
* exception: they have to call `std::terminate` then (C++ standard
* mandates so). This means exception handling routines are actually
* enforced, not omitted. This doesn't impact runtime performance (The
* Itanium C++ ABI has zero-cost exception handling), but does impact on
* generated binary size. This is bad.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/feature.h"
/** Wraps (or simulates) C++11 `noexcept` */
#if ! defined(__cplusplus)
# /* Doesn't make sense. */
# define RBIMPL_ATTR_NOEXCEPT(_) /* void */
#elif RBIMPL_HAS_FEATURE(cxx_noexcept)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
#elif __cplusplus >= 201103L
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))
#else
# define RBIMPL_ATTR_NOEXCEPT(_) /* void */
#endif
#endif /* RBIMPL_ATTR_NOEXCEPT_H */
include/ruby/internal/attr/restrict.h 0000644 00000004114 15040330606 0013743 0 ustar 00 #ifndef RBIMPL_ATTR_RESTRICT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_RESTRICT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_RESTRICT.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
/* :FIXME: config.h includes conflicting `#define restrict`. MSVC can be
* detected using `RBIMPL_COMPILER_SINCE()`, but Clang & family cannot use
* `__has_declspec_attribute()` which involves macro substitution. */
/** Wraps (or simulates) `__declspec(restrict)` */
#if RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
# define RBIMPL_ATTR_RESTRICT() __declspec(re ## strict)
#elif RBIMPL_HAS_ATTRIBUTE(malloc)
# define RBIMPL_ATTR_RESTRICT() __attribute__((__malloc__))
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_RESTRICT() _Pragma("returns_new_memory")
#else
# define RBIMPL_ATTR_RESTRICT() /* void */
#endif
#endif /* RBIMPL_ATTR_RESTRICT_H */
include/ruby/internal/attr/forceinline.h 0000644 00000003752 15040330606 0014410 0 ustar 00 #ifndef RBIMPL_ATTR_FORCEINLINE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FORCEINLINE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_FORCEINLINE.
*/
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
/**
* Wraps (or simulates) `__forceinline`. MSVC complains on declarations like
* `static inline __forceinline void foo()`. It seems MSVC's `inline` and
* `__forceinline` are mutually exclusive. We have to mimic that behaviour for
* non-MSVC compilers.
*/
#if RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
# define RBIMPL_ATTR_FORCEINLINE() __forceinline
#elif RBIMPL_HAS_ATTRIBUTE(always_inline)
# define RBIMPL_ATTR_FORCEINLINE() __attribute__((__always_inline__)) inline
#else
# define RBIMPL_ATTR_FORCEINLINE() inline
#endif
#endif /* RBIMPL_ATTR_FORCEINLINE_H */
include/ruby/internal/attr/constexpr.h 0000644 00000006700 15040330606 0014134 0 ustar 00 #ifndef RBIMPL_ATTR_CONSTEXPR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_CONSTEXPR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief #RBIMPL_ATTR_CONSTEXPR.
*/
#include "ruby/internal/has/feature.h"
#include "ruby/internal/compiler_is.h"
/** @cond INTERNAL_MACRO */
#if ! defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
#elif defined(__cpp_constexpr)
# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cpp_constexpr >= 200704L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cpp_constexpr >= 201304L)
#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 00)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 00)
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 13, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)
#elif RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)
#elif RBIMPL_HAS_FEATURE(cxx_relaxed_constexpr)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 1
#elif RBIMPL_HAS_FEATURE(cxx_constexpr)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
#else
# /* :FIXME: icpc must have constexpr but don't know how to detect. */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
#endif
/** @endcond */
/** Wraps (or simulates) C++11 `constexpr`. */
#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
# define RBIMPL_ATTR_CONSTEXPR(_) constexpr
#elif RBIMPL_HAS_ATTR_CONSTEXPR_CXX11
# define RBIMPL_ATTR_CONSTEXPR(_) RBIMPL_ATTR_CONSTEXPR_ ## _
# define RBIMPL_ATTR_CONSTEXPR_CXX11 constexpr
# define RBIMPL_ATTR_CONSTEXPR_CXX14 /* void */
#else
# define RBIMPL_ATTR_CONSTEXPR(_) /* void */
#endif
/** Enables #RBIMPL_ATTR_CONSTEXPR if and only if. ! #RUBY_DEBUG. */
#if !RUBY_DEBUG
# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) RBIMPL_ATTR_CONSTEXPR(_)
#else
# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) /* void */
#endif
#endif /* RBIMPL_ATTR_CONSTEXPR_H */
include/ruby/internal/attr/weakref.h 0000644 00000003165 15040330606 0013535 0 ustar 00 #ifndef RBIMPL_ATTR_WEAKREF_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_WEAKREF_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_WEAKREF.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((weakref))` */
#if RBIMPL_HAS_ATTRIBUTE(weakref)
# define RBIMPL_ATTR_WEAKREF(sym) __attribute__((__weakref__(# sym)))
#else
# define RBIMPL_ATTR_WEAKREF(sym) /* void */
#endif
#endif /* RBIMPL_ATTR_WEAKREF_H */
include/ruby/internal/attr/flag_enum.h 0000644 00000003303 15040330606 0014040 0 ustar 00 #ifndef RBIMPL_ATTR_FLAG_ENUM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FLAG_ENUM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_FLAG_ENUM.
* @see https://clang.llvm.org/docs/AttributeReference.html#flag_enum
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((flag_enum)` */
#if RBIMPL_HAS_ATTRIBUTE(flag_enum)
# define RBIMPL_ATTR_FLAG_ENUM() __attribute__((__flag_enum__))
#else
# define RBIMPL_ATTR_FLAG_ENUM() /* void */
#endif
#endif /* RBIMPLATTR_FLAG_ENUM_H */
include/ruby/internal/attr/artificial.h 0000644 00000004635 15040330606 0014223 0 ustar 00 #ifndef RBIMPL_ATTR_ARTIFICIAL_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ARTIFICIAL_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_ARTIFICIAL.
*
* ### Q&A ###
*
* - Q: What is this attribute? I don't get what GCC manual is talking about.
*
* - A: In short it is an attribute to manipulate GDB backtraces. The
* attribute makes the best sense when it comes with
* __attribute__((always_inline)). When a function annotated with this
* attribute gets inlined, and when you somehow look at a backtrace which
* includes such inlined call site, then the backtrace shows the caller
* and not the callee. This is handy for instance when an identical
* function is inlined more than once in a single big function. On such
* case it gets vital to know where the inlining happened in the callee.
* See also https://stackoverflow.com/a/21936099
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((artificial))` */
#if RBIMPL_HAS_ATTRIBUTE(artificial)
# define RBIMPL_ATTR_ARTIFICIAL() __attribute__((__artificial__))
#else
# define RBIMPL_ATTR_ARTIFICIAL() /* void */
#endif
#endif /* RBIMPL_ATTR_ARTIFICIAL_H */
include/ruby/internal/attr/warning.h 0000644 00000003162 15040330606 0013553 0 ustar 00 #ifndef RBIMPL_ATTR_WARNING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_WARNING_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_ATTR_WARNING.
*/
#include "ruby/internal/has/attribute.h"
/** Wraps (or simulates) `__attribute__((warning))` */
#if RBIMPL_HAS_ATTRIBUTE(warning)
# define RBIMPL_ATTR_WARNING(msg) __attribute__((__warning__ msg))
#else
# define RBIMPL_ATTR_WARNING(msg) /* void */
#endif
#endif /* RBIMPL_ATTR_WARNING_H */
include/ruby/internal/iterator.h 0000644 00000044303 15040330606 0012767 0 ustar 00 #ifndef RBIMPL_ITERATOR_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ITERATOR_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Block related APIs.
*/
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RB_BLOCK_CALL_FUNC_STRICT 1
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1
/**
* Shim for block function parameters. Historically ::rb_block_call_func_t had
* only two parameters. Over time it evolved to have much more than that. By
* using this macro you can absorb such API differences.
*
* ```CXX
* // This works since 2.1.0
* VALUE my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c));
* ```
*/
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \
VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg
/**
* This is the type of a function that the interpreter expect for C-backended
* blocks. Blocks are often written in Ruby. But C extensions might want to
* have their own blocks. In order to do so authors have to create a separate
* C function of this type, and pass its pointer to rb_block_call().
*
* ```CXX
* VALUE
* my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c))
* {
* const auto plus = rb_intern("+");
* return rb_funcall(c, plus, 1, y);
* }
*
* VALUE
* my_own_method(VALUE self)
* {
* const auto each = rb_intern("each");
* return rb_block_call(self, each, 0, 0, my_own_iterator, self);
* }
* ```
*/
typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg));
/**
* Shorthand type that represents an iterator-written-in-C function pointer.
*/
typedef rb_block_call_func *rb_block_call_func_t;
/**
* This is a shorthand of calling `obj.each`.
*
* @param[in] obj The receiver.
* @return What `obj.each` returns.
*
* @internal
*
* Does anyone still need it? This API was to use with rb_iterate(), which is
* marked deprecated (see below). Old idiom to call an iterator was:
*
* ```CXX
* VALUE recv;
* VALUE iter_func(ANYARGS);
* VALUE iter_data;
* rb_iterate(rb_each, recv, iter_func, iter_data);
* ```
*/
VALUE rb_each(VALUE obj);
/**
* Yields the block. In Ruby there is a concept called a block. You can pass
* one to a method. In a method, when called with a block, you can yield it
* using this function.
*
* ```CXX
* VALUE
* iterate(VALUE self)
* {
* extern int get_n(VALUE);
* extern VALUE get_v(VALUE, VALUE);
* const auto n = get_n(self);
*
* for (int i=0; i<n; i++) {
* auto v = get_v(self, i);
*
* rb_yield(v);
* }
* return self;
* }
* ```
*
* @param[in] val Passed to the block.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield(VALUE val);
/**
* Identical to rb_yield(), except it takes variadic number of parameters and
* pass them to the block.
*
* @param[in] n Number of parameters.
* @param[in] ... List of arguments passed to the block.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield_values(int n, ...);
/**
* Identical to rb_yield_values(), except it takes the parameters as a C array
* instead of variadic arguments.
*
* @param[in] n Number of parameters.
* @param[in] argv List of arguments passed to the block.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield_values2(int n, const VALUE *argv);
/**
* Identical to rb_yield_values2(), except you can specify how to handle the
* last element of the given array.
*
* @param[in] n Number of parameters.
* @param[in] argv List of arguments passed to the block.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `ary`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `ary`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS makes no sense here.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat);
/**
* Identical to rb_yield_values(), except it splats an array to generate the
* list of parameters.
*
* @param[in] ary Array to splat.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield_splat(VALUE ary);
/**
* Identical to rb_yield_splat(), except you can specify how to handle the last
* element of the given array.
*
* @param[in] ary Array to splat.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `ary`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `ary`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS makes no sense here.
* @exception rb_eLocalJumpError There is no block given.
* @return Evaluated value of the given block.
*/
VALUE rb_yield_splat_kw(VALUE ary, int kw_splat);
/**
* Pass a passed block.
*
* Sometimes you want to "pass" a block form one method to another. Suppose
* you have this Ruby method `foo`:
*
* ```ruby
* def foo(x, y)
* x.open(y) do |*z|
* yield(*z)
* end
* end
* ```
*
* And suppose you want to translate this into C. Then rb_yield_block()
* function is usable in this situation.
*
* ```CXX
* VALUE
* foo_translated_into_C(VALUE self, VALUE x, VALUE y)
* {
* const auto open = rb_intern("open");
*
* return rb_block_call(x, open, 1, &y, rb_yield_block, Qfalse);
* // ^^^^^^^^^^^^^^ Here.
* }
* ```
*
* @see rb_funcall_passing_block
*
* @internal
*
* @shyouhei honestly doesn't understand why this is needed, given there
* already was rb_funcall_passing_block() at the time it was implemented. If
* somebody knows its raison d'etre, please improve the document :FIXME:
*/
VALUE rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)); /* rb_block_call_func */
/**
* Determines if the current method is given a keyword argument.
*
* @retval false No keyword argument is given.
* @retval true Keyword argument(s) are given.
* @ingroup defmethod
*/
int rb_keyword_given_p(void);
/**
* Determines if the current method is given a block.
*
* @retval false No block is given.
* @retval true A block is given.
* @ingroup defmethod
*
* @internal
*
* This function should have returned a bool. But at the time it was designed
* the project was entirely written in K&R C.
*/
int rb_block_given_p(void);
/**
* Declares that the current method needs a block.
*
* @exception rb_eLocalJumpError No block given.
* @ingroup defmethod
*/
void rb_need_block(void);
#ifndef __cplusplus
RBIMPL_ATTR_DEPRECATED(("by: rb_block_call since 1.9"))
#endif
/**
* Old way to iterate a block.
*
* @deprecated This is an old API. Use rb_block_call() instead.
* @warning The passed function must at least once call a ruby method
* (to handle interrupts etc.)
* @param[in] func1 A function that could yield a value.
* @param[in,out] data1 Passed to `func1`
* @param[in] proc A function acts as a block.
* @param[in,out] data2 Passed to `proc` as the data2 parameter.
* @return What `func1` returns.
*/
VALUE rb_iterate(VALUE (*func1)(VALUE), VALUE data1, rb_block_call_func_t proc, VALUE data2);
#ifdef __cplusplus
namespace ruby {
namespace backward {
/**
* Old way to iterate a block.
*
* @deprecated This is an old API. Use rb_block_call() instead.
* @warning The passed function must at least once call a ruby method
* (to handle interrupts etc.)
* @param[in] iter A function that could yield a value.
* @param[in,out] data1 Passed to `func1`
* @param[in] bl A function acts as a block.
* @param[in,out] data2 Passed to `proc` as the data2 parameter.
* @return What `func1` returns.
*/
static inline VALUE
rb_iterate_deprecated(VALUE (*iter)(VALUE), VALUE data1, rb_block_call_func_t bl, VALUE data2)
{
return ::rb_iterate(iter, data1, bl, data2);
}}}
RBIMPL_ATTR_DEPRECATED(("by: rb_block_call since 1.9"))
VALUE rb_iterate(VALUE (*func1)(VALUE), VALUE data1, rb_block_call_func_t proc, VALUE data2);
#endif
/**
* Identical to rb_funcallv(), except it additionally passes a function as a
* block. When the method yields, `proc` is called with the yielded value as
* its first argument, and `data2` as the second. Yielded values would be
* packed into an array if multiple values are yielded at once.
*
* @param[in,out] obj Receiver.
* @param[in] mid Method signature.
* @param[in] argc Number of arguments.
* @param[in] argv Arguments passed to `obj.mid`.
* @param[in] proc A function acts as a block.
* @param[in,out] data2 Passed to `proc` as the data2 parameter.
* @return What `obj.mid` returns.
*/
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2);
/**
* Identical to rb_funcallv_kw(), except it additionally passes a function as a
* block. It can also be seen as a routine identical to rb_block_call(),
* except it handles keyword-ness of `argv[argc-1]`.
*
* @param[in,out] obj Receiver.
* @param[in] mid Method signature.
* @param[in] argc Number of arguments including the keywords.
* @param[in] argv Arguments passed to `obj.mid`.
* @param[in] proc A function acts as a block.
* @param[in,out] data2 Passed to `proc` as the data2 parameter.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @return What `obj.mid` returns.
*/
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat);
/**
* Identical to rb_rescue2(), except it does not take a list of exception
* classes. This is a shorthand of:
*
* ```CXX
* rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, (VALUE)0);
* ```
*
* @param[in] b_proc A function which potentially raises an exception.
* @param[in,out] data1 Passed to `b_proc`.
* @param[in] r_proc A function which rescues an exception in `b_proc`.
* @param[in,out] data2 The first argument of `r_proc`.
* @return The return value of `b_proc` if no exception occurs, or the
* return value of `r_proc` otherwise.
* @see rb_rescue
* @see rb_ensure
* @see rb_protect
* @ingroup exception
*/
VALUE rb_rescue(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2);
/**
* An equivalent of `rescue` clause.
*
* First it calls the function `b_proc` with `data1` as the argument. If
* nothing is thrown the function happily returns the return value of `b_proc`.
* When `b_proc` raises an exception, and the exception is a kind of one of the
* given exception classes, it then calls `r_proc` with `data2` and that
* exception. If the exception does not match any of them, it propagates.
*
* @param[in] b_proc A function which potentially raises an exception.
* @param[in,out] data1 Passed to `b_proc`.
* @param[in] r_proc A function which rescues an exception in `b_proc`.
* @param[in,out] data2 The first argument of `r_proc`.
* @param[in] ... 1 or more exception classes. Must be terminated by
* `(VALUE)0`
* @return The return value of `b_proc` if no exception occurs, or the
* return value of `r_proc` otherwise.
* @see rb_rescue
* @see rb_ensure
* @see rb_protect
* @ingroup exception
*/
VALUE rb_rescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, ...);
/**
* Identical to rb_rescue2(), except it takes `va_list` instead of variadic
* number of arguments. This is exposed to 3rd parties because inline
* functions use it. Basically you don't have to bother.
*
* @param[in] b_proc A function which potentially raises an exception.
* @param[in,out] data1 Passed to `b_proc`.
* @param[in] r_proc A function which rescues an exception in `b_proc`.
* @param[in,out] data2 The first argument of `r_proc`.
* @param[in] ap 1 or more exception classes. Must be terminated by
* `(VALUE)0`
* @return The return value of `b_proc` if no exception occurs, or the
* return value of `r_proc` otherwise.
* @see rb_rescue
* @see rb_ensure
* @see rb_protect
* @ingroup exception
*/
VALUE rb_vrescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, va_list ap);
/**
* An equivalent to `ensure` clause. Calls the function `b_proc` with `data1`
* as the argument, then calls `e_proc` with `data2` when execution terminated.
*
* @param[in] b_proc A function representing begin clause.
* @param[in,out] data1 Passed to `b_proc`.
* @param[in] e_proc A function representing ensure clause.
* @param[in,out] data2 Passed to `e_proc`.
* @retval RUBY_Qnil exception occurred inside of `b_proc`.
* @retval otherwise The return value of `b_proc`.
* @see rb_rescue
* @see rb_rescue2
* @see rb_protect
* @ingroup exception
*/
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
/**
* Executes the passed block and catches values thrown from inside of it.
*
* In case the block does not contain any throw`, this function returns the
* value of the last expression evaluated.
*
* ```CXX
* VALUE
* iter(RB_BLOCK_CALL_FUNC_ARGLIST(yielded, callback))
* {
* return INT2FIX(123);
* }
*
* VALUE
* method(VALUE self)
* {
* return rb_catch("tag", iter, Qnil); // returns 123
* }
* ```
*
* In case there do exist `throw`, Ruby searches up its execution context for a
* `catch` block. When a matching catch is found, the block stops executing
* and returns that thrown value instead.
*
* ```CXX
* VALUE
* iter(RB_BLOCK_CALL_FUNC_ARGLIST(yielded, callback))
* {
* rb_throw("tag", 456);
* return INT2FIX(123);
* }
*
* VALUE
* method(VALUE self)
* {
* return rb_catch("tag", iter, Qnil); // returns 456
* }
* ```
*
* @param[in] tag Arbitrary tag string.
* @param[in] func Function pointer that acts as a block.
* @param[in,out] data Extra parameter passed to `func`.
* @return Either caught value for `tag`, or the return value of `func`
* if nothing is thrown.
*/
VALUE rb_catch(const char *tag, rb_block_call_func_t func, VALUE data);
/**
* Identical to rb_catch(), except it catches arbitrary Ruby objects.
*
* @param[in] tag Arbitrary tag object.
* @param[in] func Function pointer that acts as a block.
* @param[in,out] data Extra parameter passed to `func`.
* @return Either caught value for `tag`, or the return value of `func`
* if nothing is thrown.
*/
VALUE rb_catch_obj(VALUE tag, rb_block_call_func_t func, VALUE data);
RBIMPL_ATTR_NORETURN()
/**
* Transfers control to the end of the active `catch` block waiting for `tag`.
* Raises rb_eUncughtThrow if there is no `catch` block for the tag. The
* second parameter supplies a return value for the `catch` block, which
* otherwise defaults to ::RUBY_Qnil. For examples, see rb_catch().
*
* @param[in] tag Tag string.
* @param[in] val Value to throw.
* @exception rb_eUncughtThrow There is no corresponding `catch` clause.
* @note It never returns.
*/
void rb_throw(const char *tag, VALUE val);
RBIMPL_ATTR_NORETURN()
/**
* Identical to rb_throw(), except it allows arbitrary Ruby object to become a
* tag.
*
* @param[in] tag Arbitrary object.
* @param[in] val Value to throw.
* @exception rb_eUncughtThrow There is no corresponding `catch` clause.
* @note It never returns.
*/
void rb_throw_obj(VALUE tag, VALUE val);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_ITERATOR_H */
include/ruby/internal/globals.h 0000644 00000023430 15040330606 0012557 0 ustar 00 #ifndef RBIMPL_GLOBALS_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GLOBALS_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Ruby-level global variables / constants, visible from C.
*/
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
/**
* @defgroup object Core objects and their operations
*
* @internal
*
* There are several questionable constants listed in this header file. They
* are intentionally left untouched for purely academic backwards compatibility
* concerns. But for instance do any one of 3rd party extension libraries even
* need to know that there is NameError::Message?
*
* @endinternal
*
* @{
*/
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RUBY_INTEGER_UNIFICATION 1
RUBY_EXTERN VALUE rb_mKernel; /**< `Kernel` module. */
RUBY_EXTERN VALUE rb_mComparable; /**< `Comparable` module. */
RUBY_EXTERN VALUE rb_mEnumerable; /**< `Enumerable` module. */
RUBY_EXTERN VALUE rb_mErrno; /**< `Errno` module. */
RUBY_EXTERN VALUE rb_mFileTest; /**< `FileTest` module. */
RUBY_EXTERN VALUE rb_mGC; /**< `GC` module. */
RUBY_EXTERN VALUE rb_mMath; /**< `Math` module. */
RUBY_EXTERN VALUE rb_mProcess; /**< `Process` module. */
RUBY_EXTERN VALUE rb_mWaitReadable; /**< `IO::WaitReadable` module. */
RUBY_EXTERN VALUE rb_mWaitWritable; /**< `IO::WaitReadable` module. */
RUBY_EXTERN VALUE rb_cBasicObject; /**< `BasicObject` class. */
RUBY_EXTERN VALUE rb_cObject; /**< `Object` class. */
RUBY_EXTERN VALUE rb_cArray; /**< `Array` class. */
RUBY_EXTERN VALUE rb_cBinding; /**< `Binding` class. */
RUBY_EXTERN VALUE rb_cClass; /**< `Class` class. */
RUBY_EXTERN VALUE rb_cDir; /**< `Dir` class. */
RUBY_EXTERN VALUE rb_cEncoding; /**< `Encoding` class. */
RUBY_EXTERN VALUE rb_cEnumerator; /**< `Enumerator` class. */
RUBY_EXTERN VALUE rb_cFalseClass; /**< `FalseClass` class. */
RUBY_EXTERN VALUE rb_cFile; /**< `File` class. */
RUBY_EXTERN VALUE rb_cComplex; /**< `Complex` class. */
RUBY_EXTERN VALUE rb_cFloat; /**< `Float` class. */
RUBY_EXTERN VALUE rb_cHash; /**< `Hash` class. */
RUBY_EXTERN VALUE rb_cIO; /**< `IO` class. */
RUBY_EXTERN VALUE rb_cInteger; /**< `Module` class. */
RUBY_EXTERN VALUE rb_cMatch; /**< `MatchData` class. */
RUBY_EXTERN VALUE rb_cMethod; /**< `Method` class. */
RUBY_EXTERN VALUE rb_cModule; /**< `Module` class. */
RUBY_EXTERN VALUE rb_cRefinement; /**< `Refinement` class. */
RUBY_EXTERN VALUE rb_cNameErrorMesg; /**< `NameError::Message` class. */
RUBY_EXTERN VALUE rb_cNilClass; /**< `NilClass` class. */
RUBY_EXTERN VALUE rb_cNumeric; /**< `Numeric` class. */
RUBY_EXTERN VALUE rb_cProc; /**< `Proc` class. */
RUBY_EXTERN VALUE rb_cRandom; /**< `Random` class. */
RUBY_EXTERN VALUE rb_cRange; /**< `Range` class. */
RUBY_EXTERN VALUE rb_cRational; /**< `Rational` class. */
RUBY_EXTERN VALUE rb_cRegexp; /**< `Regexp` class. */
RUBY_EXTERN VALUE rb_cStat; /**< `File::Stat` class. */
RUBY_EXTERN VALUE rb_cString; /**< `String` class. */
RUBY_EXTERN VALUE rb_cStruct; /**< `Struct` class. */
RUBY_EXTERN VALUE rb_cSymbol; /**< `Sumbol` class. */
RUBY_EXTERN VALUE rb_cThread; /**< `Thread` class. */
RUBY_EXTERN VALUE rb_cTime; /**< `Time` class. */
RUBY_EXTERN VALUE rb_cTrueClass; /**< `TrueClass` class. */
RUBY_EXTERN VALUE rb_cUnboundMethod; /**< `UnboundMethod` class. */
/**
* @}
* @addtogroup exception
* @{
*/
RUBY_EXTERN VALUE rb_eException; /**< Mother of all exceptions. */
RUBY_EXTERN VALUE rb_eStandardError; /**< `StandardError` exception. */
RUBY_EXTERN VALUE rb_eSystemExit; /**< `SystemExit` exception. */
RUBY_EXTERN VALUE rb_eInterrupt; /**< `Interrupt` exception. */
RUBY_EXTERN VALUE rb_eSignal; /**< `SignalException` exception. */
RUBY_EXTERN VALUE rb_eFatal; /**< `fatal` exception. */
RUBY_EXTERN VALUE rb_eArgError; /**< `ArgumentError` exception. */
RUBY_EXTERN VALUE rb_eEOFError; /**< `EOFError` exception. */
RUBY_EXTERN VALUE rb_eIndexError; /**< `IndexError` exception. */
RUBY_EXTERN VALUE rb_eStopIteration; /**< `StopIteration` exception. */
RUBY_EXTERN VALUE rb_eKeyError; /**< `KeyError` exception. */
RUBY_EXTERN VALUE rb_eRangeError; /**< `RangeError` exception. */
RUBY_EXTERN VALUE rb_eIOError; /**< `IOError` exception. */
RUBY_EXTERN VALUE rb_eRuntimeError; /**< `RuntimeError` exception. */
RUBY_EXTERN VALUE rb_eFrozenError; /**< `FrozenError` exception. */
RUBY_EXTERN VALUE rb_eSecurityError; /**< `SecurityError` exception. */
RUBY_EXTERN VALUE rb_eSystemCallError; /**< `SystemCallError` exception. */
RUBY_EXTERN VALUE rb_eThreadError; /**< `ThreadError` exception. */
RUBY_EXTERN VALUE rb_eTypeError; /**< `TypeError` exception. */
RUBY_EXTERN VALUE rb_eZeroDivError; /**< `ZeroDivisionError` exception. */
RUBY_EXTERN VALUE rb_eNotImpError; /**< `NotImplementedError` exception. */
RUBY_EXTERN VALUE rb_eNoMemError; /**< `NoMemoryError` exception. */
RUBY_EXTERN VALUE rb_eNoMethodError; /**< `NoMethodError` exception. */
RUBY_EXTERN VALUE rb_eFloatDomainError; /**< `FloatDomainError` exception. */
RUBY_EXTERN VALUE rb_eLocalJumpError; /**< `LocalJumpError` exception. */
RUBY_EXTERN VALUE rb_eSysStackError; /**< `SystemStackError` exception. */
RUBY_EXTERN VALUE rb_eRegexpError; /**< `RegexpError` exception. */
RUBY_EXTERN VALUE rb_eEncodingError; /**< `EncodingError` exception. */
RUBY_EXTERN VALUE rb_eEncCompatError; /**< `Encoding::CompatibilityError` exception. */
RUBY_EXTERN VALUE rb_eNoMatchingPatternError; /**< `NoMatchingPatternError` exception. */
RUBY_EXTERN VALUE rb_eNoMatchingPatternKeyError; /**< `NoMatchingPatternKeyError` exception. */
RUBY_EXTERN VALUE rb_eScriptError; /**< `ScriptError` exception. */
RUBY_EXTERN VALUE rb_eNameError; /**< `NameError` exception. */
RUBY_EXTERN VALUE rb_eSyntaxError; /**< `SyntaxError` exception. */
RUBY_EXTERN VALUE rb_eLoadError; /**< `LoadError` exception. */
RUBY_EXTERN VALUE rb_eMathDomainError; /**< `Math::DomainError` exception. */
/**
* @}
* @addtogroup object
* @{
*/
RUBY_EXTERN VALUE rb_stdin; /**< `STDIN` constant. */
RUBY_EXTERN VALUE rb_stdout; /**< `STDOUT` constant. */
RUBY_EXTERN VALUE rb_stderr; /**< `STDERR` constant. */
RBIMPL_ATTR_PURE()
/**
* Object to class mapping function. Every object have its class. This
* function obtains that.
*
* @param[in] obj Target object to query.
* @return The class of the given object.
*
* @internal
*
* This function is a super-duper hot path. Optimised targeting modern C
* compilers and x86_64 architecture.
*/
static inline VALUE
rb_class_of(VALUE obj)
{
if (! RB_SPECIAL_CONST_P(obj)) {
return RBASIC_CLASS(obj);
}
else if (obj == RUBY_Qfalse) {
return rb_cFalseClass;
}
else if (obj == RUBY_Qnil) {
return rb_cNilClass;
}
else if (obj == RUBY_Qtrue) {
return rb_cTrueClass;
}
else if (RB_FIXNUM_P(obj)) {
return rb_cInteger;
}
else if (RB_STATIC_SYM_P(obj)) {
return rb_cSymbol;
}
else if (RB_FLONUM_P(obj)) {
return rb_cFloat;
}
#if !RUBY_DEBUG
RBIMPL_UNREACHABLE_RETURN(Qfalse);
#else
RUBY_ASSERT_FAIL("unexpected type");
#endif
}
#define CLASS_OF rb_class_of /**< @old{rb_class_of} */
RBIMPL_SYMBOL_EXPORT_END()
/** @} */
#endif /* RBIMPL_GLOBALS_H */
include/ruby/internal/value_type.h 0000644 00000034171 15040330606 0013315 0 ustar 00 #ifndef RBIMPL_VALUE_TYPE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VALUE_TYPE_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines enum ::ruby_value_type.
*/
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/enum_extensibility.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
#if defined(T_DATA)
/*
* :!BEWARE!: (Recent?) Solaris' <nfs/nfs.h> have conflicting definition of
* T_DATA. Let us stop here. Please have a workaround like this:
*
* ```C
* #include <ruby/ruby.h> // <- Include this one first.
* #undef T_DATA // <- ... and stick to RUBY_T_DATA forever.
* #include <nfs/nfs.h> // <- OS-provided T_DATA introduced.
* ```
*
* See also [ruby-core:4261]
*/
# error Bail out due to conflicting definition of T_DATA.
#endif
#define T_ARRAY RUBY_T_ARRAY /**< @old{RUBY_T_ARRAY} */
#define T_BIGNUM RUBY_T_BIGNUM /**< @old{RUBY_T_BIGNUM} */
#define T_CLASS RUBY_T_CLASS /**< @old{RUBY_T_CLASS} */
#define T_COMPLEX RUBY_T_COMPLEX /**< @old{RUBY_T_COMPLEX} */
#define T_DATA RUBY_T_DATA /**< @old{RUBY_T_DATA} */
#define T_FALSE RUBY_T_FALSE /**< @old{RUBY_T_FALSE} */
#define T_FILE RUBY_T_FILE /**< @old{RUBY_T_FILE} */
#define T_FIXNUM RUBY_T_FIXNUM /**< @old{RUBY_T_FIXNUM} */
#define T_FLOAT RUBY_T_FLOAT /**< @old{RUBY_T_FLOAT} */
#define T_HASH RUBY_T_HASH /**< @old{RUBY_T_HASH} */
#define T_ICLASS RUBY_T_ICLASS /**< @old{RUBY_T_ICLASS} */
#define T_IMEMO RUBY_T_IMEMO /**< @old{RUBY_T_IMEMO} */
#define T_MASK RUBY_T_MASK /**< @old{RUBY_T_MASK} */
#define T_MATCH RUBY_T_MATCH /**< @old{RUBY_T_MATCH} */
#define T_MODULE RUBY_T_MODULE /**< @old{RUBY_T_MODULE} */
#define T_MOVED RUBY_T_MOVED /**< @old{RUBY_T_MOVED} */
#define T_NIL RUBY_T_NIL /**< @old{RUBY_T_NIL} */
#define T_NODE RUBY_T_NODE /**< @old{RUBY_T_NODE} */
#define T_NONE RUBY_T_NONE /**< @old{RUBY_T_NONE} */
#define T_OBJECT RUBY_T_OBJECT /**< @old{RUBY_T_OBJECT} */
#define T_RATIONAL RUBY_T_RATIONAL /**< @old{RUBY_T_RATIONAL} */
#define T_REGEXP RUBY_T_REGEXP /**< @old{RUBY_T_REGEXP} */
#define T_STRING RUBY_T_STRING /**< @old{RUBY_T_STRING} */
#define T_STRUCT RUBY_T_STRUCT /**< @old{RUBY_T_STRUCT} */
#define T_SYMBOL RUBY_T_SYMBOL /**< @old{RUBY_T_SYMBOL} */
#define T_TRUE RUBY_T_TRUE /**< @old{RUBY_T_TRUE} */
#define T_UNDEF RUBY_T_UNDEF /**< @old{RUBY_T_UNDEF} */
#define T_ZOMBIE RUBY_T_ZOMBIE /**< @old{RUBY_T_ZOMBIE} */
#define BUILTIN_TYPE RB_BUILTIN_TYPE /**< @old{RB_BUILTIN_TYPE} */
#define DYNAMIC_SYM_P RB_DYNAMIC_SYM_P /**< @old{RB_DYNAMIC_SYM_P} */
#define RB_INTEGER_TYPE_P rb_integer_type_p /**< @old{rb_integer_type_p} */
#define SYMBOL_P RB_SYMBOL_P /**< @old{RB_SYMBOL_P} */
#define rb_type_p RB_TYPE_P /**< @alias{RB_TYPE_P} */
/** @cond INTERNAL_MACRO */
#define RB_BUILTIN_TYPE RB_BUILTIN_TYPE
#define RB_DYNAMIC_SYM_P RB_DYNAMIC_SYM_P
#define RB_FLOAT_TYPE_P RB_FLOAT_TYPE_P
#define RB_SYMBOL_P RB_SYMBOL_P
#define RB_TYPE_P RB_TYPE_P
#define Check_Type Check_Type
#if !RUBY_DEBUG
# define RBIMPL_ASSERT_TYPE(v, t) RBIMPL_ASSERT_OR_ASSUME(RB_TYPE_P((v), (t)))
#else
# define RBIMPL_ASSERT_TYPE Check_Type
#endif
/** @endcond */
/** @old{rb_type} */
#define TYPE(_) RBIMPL_CAST((int)rb_type(_))
/** C-level type of an object. */
enum
RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
ruby_value_type {
RUBY_T_NONE = 0x00, /**< Non-object (swept etc.) */
RUBY_T_OBJECT = 0x01, /**< @see struct ::RObject */
RUBY_T_CLASS = 0x02, /**< @see struct ::RClass and ::rb_cClass */
RUBY_T_MODULE = 0x03, /**< @see struct ::RClass and ::rb_cModule */
RUBY_T_FLOAT = 0x04, /**< @see struct ::RFloat */
RUBY_T_STRING = 0x05, /**< @see struct ::RString */
RUBY_T_REGEXP = 0x06, /**< @see struct ::RRegexp */
RUBY_T_ARRAY = 0x07, /**< @see struct ::RArray */
RUBY_T_HASH = 0x08, /**< @see struct ::RHash */
RUBY_T_STRUCT = 0x09, /**< @see struct ::RStruct */
RUBY_T_BIGNUM = 0x0a, /**< @see struct ::RBignum */
RUBY_T_FILE = 0x0b, /**< @see struct ::RFile */
RUBY_T_DATA = 0x0c, /**< @see struct ::RTypedData */
RUBY_T_MATCH = 0x0d, /**< @see struct ::RMatch */
RUBY_T_COMPLEX = 0x0e, /**< @see struct ::RComplex */
RUBY_T_RATIONAL = 0x0f, /**< @see struct ::RRational */
RUBY_T_NIL = 0x11, /**< @see ::RUBY_Qnil */
RUBY_T_TRUE = 0x12, /**< @see ::RUBY_Qfalse */
RUBY_T_FALSE = 0x13, /**< @see ::RUBY_Qtrue */
RUBY_T_SYMBOL = 0x14, /**< @see struct ::RSymbol */
RUBY_T_FIXNUM = 0x15, /**< Integers formerly known as Fixnums. */
RUBY_T_UNDEF = 0x16, /**< @see ::RUBY_Qundef */
RUBY_T_IMEMO = 0x1a, /**< @see struct ::RIMemo */
RUBY_T_NODE = 0x1b, /**< @see struct ::RNode */
RUBY_T_ICLASS = 0x1c, /**< Hidden classes known as IClasses. */
RUBY_T_ZOMBIE = 0x1d, /**< @see struct ::RZombie */
RUBY_T_MOVED = 0x1e, /**< @see struct ::RMoved */
RUBY_T_MASK = 0x1f /**< Bitmask of ::ruby_value_type. */
};
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_COLD()
/**
* @private
*
* This was the old implementation of Check_Type(), but they diverged. This
* one remains for theoretical backwards compatibility. People normally need
* not use it.
*
* @param[in] obj An object.
* @param[in] t A type.
* @exception rb_eTypeError `obj` is not of type `t`.
* @exception rb_eFatal `obj` is corrupt.
* @post Upon successful return `obj` is guaranteed to have type `t`.
*
* @internal
*
* The second argument shall have been enum ::ruby_value_type. But at the time
* matz designed this function he still used K&R C. There was no such thing
* like a function prototype. We can no longer change this API.
*/
void rb_check_type(VALUE obj, int t);
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries the type of the object.
*
* @param[in] obj Object in question.
* @pre `obj` must not be a special constant.
* @return The type of `obj`.
*/
static inline enum ruby_value_type
RB_BUILTIN_TYPE(VALUE obj)
{
RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
#if 0 && defined __GNUC__ && !defined __clang__
/* Don't move the access to `flags` before the preceding
* RB_SPECIAL_CONST_P check. */
__asm volatile("": : :"memory");
#endif
VALUE ret = RBASIC(obj)->flags & RUBY_T_MASK;
return RBIMPL_CAST((enum ruby_value_type)ret);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* Queries if the object is an instance of ::rb_cInteger.
*
* @param[in] obj Object in question.
* @retval true It is.
* @retval false It isn't.
*/
static inline bool
rb_integer_type_p(VALUE obj)
{
if (RB_FIXNUM_P(obj)) {
return true;
}
else if (RB_SPECIAL_CONST_P(obj)) {
return false;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_BIGNUM;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
* Identical to RB_BUILTIN_TYPE(), except it can also accept special constants.
*
* @param[in] obj Object in question.
* @return The type of `obj`.
*/
static inline enum ruby_value_type
rb_type(VALUE obj)
{
if (! RB_SPECIAL_CONST_P(obj)) {
return RB_BUILTIN_TYPE(obj);
}
else if (obj == RUBY_Qfalse) {
return RUBY_T_FALSE;
}
else if (obj == RUBY_Qnil) {
return RUBY_T_NIL;
}
else if (obj == RUBY_Qtrue) {
return RUBY_T_TRUE;
}
else if (obj == RUBY_Qundef) {
return RUBY_T_UNDEF;
}
else if (RB_FIXNUM_P(obj)) {
return RUBY_T_FIXNUM;
}
else if (RB_STATIC_SYM_P(obj)) {
return RUBY_T_SYMBOL;
}
else {
RBIMPL_ASSUME(RB_FLONUM_P(obj));
return RUBY_T_FLOAT;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries if the object is an instance of ::rb_cFloat.
*
* @param[in] obj Object in question.
* @retval true It is.
* @retval false It isn't.
*/
static inline bool
RB_FLOAT_TYPE_P(VALUE obj)
{
if (RB_FLONUM_P(obj)) {
return true;
}
else if (RB_SPECIAL_CONST_P(obj)) {
return false;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_FLOAT;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries if the object is a dynamic symbol.
*
* @param[in] obj Object in question.
* @retval true It is.
* @retval false It isn't.
*/
static inline bool
RB_DYNAMIC_SYM_P(VALUE obj)
{
if (RB_SPECIAL_CONST_P(obj)) {
return false;
}
else {
return RB_BUILTIN_TYPE(obj) == RUBY_T_SYMBOL;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries if the object is an instance of ::rb_cSymbol.
*
* @param[in] obj Object in question.
* @retval true It is.
* @retval false It isn't.
*/
static inline bool
RB_SYMBOL_P(VALUE obj)
{
return RB_STATIC_SYM_P(obj) || RB_DYNAMIC_SYM_P(obj);
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_FORCEINLINE()
/**
* @private
*
* This is an implementation detail of RB_TYPE_P(). Just don't use it.
*
* @param[in] obj An object.
* @param[in] t A type.
* @retval true `obj` is of type `t`.
* @retval false Otherwise.
*/
static bool
rbimpl_RB_TYPE_P_fastpath(VALUE obj, enum ruby_value_type t)
{
if (t == RUBY_T_TRUE) {
return obj == RUBY_Qtrue;
}
else if (t == RUBY_T_FALSE) {
return obj == RUBY_Qfalse;
}
else if (t == RUBY_T_NIL) {
return obj == RUBY_Qnil;
}
else if (t == RUBY_T_UNDEF) {
return obj == RUBY_Qundef;
}
else if (t == RUBY_T_FIXNUM) {
return RB_FIXNUM_P(obj);
}
else if (t == RUBY_T_SYMBOL) {
return RB_SYMBOL_P(obj);
}
else if (t == RUBY_T_FLOAT) {
return RB_FLOAT_TYPE_P(obj);
}
else if (RB_SPECIAL_CONST_P(obj)) {
return false;
}
else if (t == RB_BUILTIN_TYPE(obj)) {
return true;
}
else {
return false;
}
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
* Queries if the given object is of given type.
*
* @param[in] obj An object.
* @param[in] t A type.
* @retval true `obj` is of type `t`.
* @retval false Otherwise.
*
* @internal
*
* This function is a super-duper hot path. Optimised targeting modern C
* compilers and x86_64 architecture.
*/
static inline bool
RB_TYPE_P(VALUE obj, enum ruby_value_type t)
{
if (RBIMPL_CONSTANT_P(t)) {
return rbimpl_RB_TYPE_P_fastpath(obj, t);
}
else {
return t == rb_type(obj);
}
}
/** @cond INTERNAL_MACRO */
/* Clang, unlike GCC, cannot propagate __builtin_constant_p beyond function
* boundary. */
#if defined(__clang__)
# undef RB_TYPE_P
# define RB_TYPE_P(obj, t) \
(RBIMPL_CONSTANT_P(t) ? \
rbimpl_RB_TYPE_P_fastpath((obj), (t)) : \
(RB_TYPE_P)((obj), (t)))
#endif
/* clang 3.x (4.2 compatible) can't eliminate CSE of RB_BUILTIN_TYPE
* in inline function and caller function
* See also 8998c06461ea0bef11b3aeb30b6d2ab71c8762ba
*/
#if RBIMPL_COMPILER_BEFORE(Clang, 4, 0, 0)
# undef rb_integer_type_p
# define rb_integer_type_p(obj) \
__extension__ ({ \
const VALUE integer_type_obj = (obj); \
(RB_FIXNUM_P(integer_type_obj) || \
(!RB_SPECIAL_CONST_P(integer_type_obj) && \
RB_BUILTIN_TYPE(integer_type_obj) == RUBY_T_BIGNUM)); \
})
#endif
/** @endcond */
RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
* @private
* Defined in ruby/internal/core/rtypeddata.h
*/
static inline bool rbimpl_rtypeddata_p(VALUE obj);
RBIMPL_ATTR_ARTIFICIAL()
/**
* Identical to RB_TYPE_P(), except it raises exceptions on predication
* failure.
*
* @param[in] v An object.
* @param[in] t A type.
* @exception rb_eTypeError `obj` is not of type `t`.
* @exception rb_eFatal `obj` is corrupt.
* @post Upon successful return `obj` is guaranteed to have type `t`.
*/
static inline void
Check_Type(VALUE v, enum ruby_value_type t)
{
if (RB_UNLIKELY(! RB_TYPE_P(v, t))) {
goto unexpected_type;
}
else if (t == RUBY_T_DATA && rbimpl_rtypeddata_p(v)) {
/* Typed data is not simple `T_DATA`, see `rb_check_type` */
goto unexpected_type;
}
else {
return;
}
unexpected_type:
rb_unexpected_type(v, t);
}
#endif /* RBIMPL_VALUE_TYPE_H */
include/ruby/internal/constant_p.h 0000644 00000003547 15040330606 0013313 0 ustar 00 #ifndef RBIMPL_CONSTANT_P_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CONSTANT_P_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Defines #RBIMPL_CONSTANT_P.
*
* Note that __builtin_constant_p can be applicable inside of inline functions,
* according to GCC manual. Clang lacks that feature, though.
*
* @see https://bugs.llvm.org/show_bug.cgi?id=4898
* @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
*/
#include "ruby/internal/has/builtin.h"
/** Wraps (or simulates) `__builtin_constant_p` */
#if RBIMPL_HAS_BUILTIN(__builtin_constant_p)
# define RBIMPL_CONSTANT_P(expr) __builtin_constant_p(expr)
#else
# define RBIMPL_CONSTANT_P(expr) 0
#endif
#endif /* RBIMPL_CONSTANT_P_H */
include/ruby/digest.h 0000644 00000003312 15040330606 0010574 0 ustar 00 /************************************************
digest.h - header file for ruby digest modules
$Author$
created at: Fri May 25 08:54:56 JST 2001
Copyright (C) 2001-2006 Akinori MUSHA
$RoughId: digest.h,v 1.3 2001/07/13 15:38:27 knu Exp $
$Id$
************************************************/
#include "ruby.h"
#define RUBY_DIGEST_API_VERSION 3
typedef int (*rb_digest_hash_init_func_t)(void *);
typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
typedef int (*rb_digest_hash_finish_func_t)(void *, unsigned char *);
typedef struct {
int api_version;
size_t digest_len;
size_t block_len;
size_t ctx_size;
rb_digest_hash_init_func_t init_func;
rb_digest_hash_update_func_t update_func;
rb_digest_hash_finish_func_t finish_func;
} rb_digest_metadata_t;
#define DEFINE_UPDATE_FUNC_FOR_UINT(name) \
void \
rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \
{ \
const unsigned int stride = 16384; \
\
for (; size > stride; size -= stride, ptr += stride) { \
name##_Update(ctx, ptr, stride); \
} \
if (size > 0) name##_Update(ctx, ptr, size); \
}
#define DEFINE_FINISH_FUNC_FROM_FINAL(name) \
int \
rb_digest_##name##_finish(void *ctx, unsigned char *ptr) \
{ \
return name##_Final(ptr, ctx); \
}
static inline VALUE
rb_digest_namespace(void)
{
rb_require("digest");
return rb_path2class("Digest");
}
static inline ID
rb_id_metadata(void)
{
return rb_intern_const("metadata");
}
static inline VALUE
rb_digest_make_metadata(const rb_digest_metadata_t *meta)
{
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
return rb_obj_freeze(Data_Wrap_Struct(0, 0, 0, (void *)meta));
}
include/ruby/assert.h 0000644 00000017064 15040330606 0010627 0 ustar 00 #ifndef RUBY_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ASSERT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @date Wed May 18 00:21:44 JST 1994
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
*/
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/backward/2/assume.h"
/* RUBY_NDEBUG is very simple: after everything described below are done,
* define it with either NDEBUG is undefined (=0) or defined (=1). It is truly
* subordinate.
*
* RUBY_DEBUG versus NDEBUG is complicated. Assertions shall be:
*
* | -UNDEBUG | -DNDEBUG
* ---------------+----------+---------
* -URUBY_DEBUG | (*1) | disabled
* -DRUBY_DEBUG=0 | disabled | disabled
* -DRUBY_DEBUG=1 | enabled | (*2)
* -DRUBY_DEBUG | enabled | (*2)
*
* where:
*
* - (*1): Assertions shall be silently disabled, no warnings, in favour of
* commit 21991e6ca59274e41a472b5256bd3245f6596c90.
*
* - (*2): Compile-time warnings shall be issued.
*/
/** @cond INTERNAL_MACRO */
/*
* Pro tip: `!!RUBY_DEBUG-1` expands to...
*
* - `!!(-1)` (== `!0` == `1`) when RUBY_DEBUG is defined to be empty,
* - `(!!0)-1` (== `0-1` == `-1`) when RUBY_DEBUG is defined as 0, and
* - `(!!n)-1` (== `1-1` == `0`) when RUBY_DEBUG is defined as something else.
*/
#if ! defined(RUBY_DEBUG)
# define RBIMPL_RUBY_DEBUG 0
#elif !!RUBY_DEBUG-1 < 0
# define RBIMPL_RUBY_DEBUG 0
#else
# define RBIMPL_RUBY_DEBUG 1
#endif
/*
* ISO/IEC 9899 (all past versions) says that "If NDEBUG is defined as a macro
* name at the point in the source file where <assert.h> is included, ..."
* which means we must not take its defined value into account.
*/
#if defined(NDEBUG)
# define RBIMPL_NDEBUG 1
#else
# define RBIMPL_NDEBUG 0
#endif
/** @endcond */
/* Here we go... */
#undef RUBY_DEBUG
#undef RUBY_NDEBUG
#undef NDEBUG
#if defined(__DOXYGEN__)
# /** Define this macro when you want assertions. */
# define RUBY_DEBUG 0
# /** Define this macro when you don't want assertions. */
# define NDEBUG
# /** This macro is basically the same as #NDEBUG */
# define RUBY_NDEBUG 1
#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 0)
# /* Assertions disabled as per request, no conflicts. */
# define RUBY_DEBUG 0
# define RUBY_NDEBUG 1
# define NDEBUG
#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 1)
# /* Assertions enabled as per request, no conflicts. */
# define RUBY_DEBUG 1
# define RUBY_NDEBUG 0
# /* keep NDEBUG undefined */
#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
# /* The (*1) situation in above diagram. */
# define RUBY_DEBUG 0
# define RUBY_NDEBUG 1
# define NDEBUG
#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 1)
# /* The (*2) situation in above diagram. */
# define RUBY_DEBUG 1
# define RUBY_NDEBUG 0
# /* keep NDEBUG undefined */
# if defined(_MSC_VER)
# pragma message("NDEBUG is ignored because RUBY_DEBUG>0.")
# elif defined(__GNUC__)
# pragma GCC warning "NDEBUG is ignored because RUBY_DEBUG>0."
# else
# error NDEBUG is ignored because RUBY_DEBUG>0.
# endif
#endif
#undef RBIMPL_NDEBUG
#undef RBIMPL_RUBY_DEBUG
/** @cond INTERNAL_MACRO */
#define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
RBIMPL_SYMBOL_EXPORT_END()
#ifdef RUBY_FUNCTION_NAME_STRING
# define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
#else
# define RBIMPL_ASSERT_FUNC RBIMPL_CAST((const char *)0)
#endif
/** @endcond */
/**
* Prints the given message, and terminates the entire process abnormally.
*
* @param mesg The message to display.
*/
#define RUBY_ASSERT_FAIL(mesg) \
rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
/**
* Asserts that the expression is truthy. If not aborts with the message.
*
* @param expr What supposedly evaluates to true.
* @param mesg The message to display on failure.
*/
#define RUBY_ASSERT_MESG(expr, mesg) \
(RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
/**
* A variant of #RUBY_ASSERT that does not interface with #RUBY_DEBUG.
*
* @copydetails #RUBY_ASSERT
*/
#define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
/**
* Asserts that the given expression is truthy if and only if #RUBY_DEBUG is truthy.
*
* @param expr What supposedly evaluates to true.
*/
#if RUBY_DEBUG
# define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
#else
# define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
#endif
/**
* A variant of #RUBY_ASSERT that interfaces with #NDEBUG instead of
* #RUBY_DEBUG. This almost resembles `assert` C standard macro, except minor
* implementation details.
*
* @copydetails #RUBY_ASSERT
*/
/* Currently `RUBY_DEBUG == ! defined(NDEBUG)` is always true. There is no
* difference any longer between this one and `RUBY_ASSERT`. */
#if defined(NDEBUG)
# define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
#else
# define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
#endif
/**
* @copydoc #RUBY_ASSERT_WHEN
* @param mesg The message to display on failure.
*/
#if RUBY_DEBUG
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
#else
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
#endif
/**
* A variant of #RUBY_ASSERT that asserts when either #RUBY_DEBUG or `cond`
* parameter is truthy.
*
* @param cond Extra condition that shall hold for assertion to take effect.
* @param expr What supposedly evaluates to true.
*/
#define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
/**
* This is either #RUBY_ASSERT or #RBIMPL_ASSUME, depending on #RUBY_DEBUG.
*
* @copydetails #RUBY_ASSERT
*/
#if RUBY_DEBUG
# define RBIMPL_ASSERT_OR_ASSUME(expr) RUBY_ASSERT_ALWAYS(expr)
#elif RBIMPL_COMPILER_BEFORE(Clang, 7, 0, 0)
# /* See commit 67d259c5dccd31fe49d417fec169977712ffdf10 */
# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
#elif defined(RUBY_ASSERT_NOASSUME)
# /* See commit d300a734414ef6de7e8eb563b7cc4389c455ed08 */
# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
#elif ! defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
#else
# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSUME(expr)
#endif
#endif /* RUBY_ASSERT_H */
include/ruby/ruby.h 0000644 00000026723 15040330606 0010311 0 ustar 00 #ifndef RUBY_RUBY_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_H 1
/**
* @file
* @author $Author$
* @date Thu Jun 10 14:26:32 JST 1993
* @copyright Copyright (C) 1993-2008 Yukihiro Matsumoto
* @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
* @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/internal/config.h"
/* @shyouhei doesn't understand why we need <intrinsics.h> at this very
* beginning of the entire <ruby.h> circus. */
#ifdef HAVE_INTRINSICS_H
# include <intrinsics.h>
#endif
#include <stdarg.h>
#include "defines.h"
#include "ruby/internal/abi.h"
#include "ruby/internal/anyargs.h"
#include "ruby/internal/arithmetic.h"
#include "ruby/internal/core.h"
#include "ruby/internal/ctype.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/eval.h"
#include "ruby/internal/event.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/gc.h"
#include "ruby/internal/glob.h"
#include "ruby/internal/globals.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/interpreter.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/memory.h"
#include "ruby/internal/method.h"
#include "ruby/internal/module.h"
#include "ruby/internal/newobj.h"
#include "ruby/internal/rgengc.h"
#include "ruby/internal/scan_args.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/symbol.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/variable.h"
#include "ruby/assert.h"
#include "ruby/backward/2/assume.h"
#include "ruby/backward/2/inttypes.h"
#include "ruby/backward/2/limits.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* Module#methods, #singleton_methods and so on return Symbols */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define USE_SYMBOL_AS_METHOD_NAME 1
/**
* Converts an object to a path. It first tries `#to_path` method if any, then
* falls back to `#to_str` method.
*
* @param[in] obj Arbitrary ruby object.
* @exception rb_eArgError `obj` contains a NUL byte.
* @exception rb_eTypeError `obj` is not path-ish.
* @exception rb_eEncCompatError No encoding conversion from `obj` to path.
* @return Converted path object.
*/
VALUE rb_get_path(VALUE obj);
/**
* Ensures that the parameter object is a path.
*
* @param[in,out] v Arbitrary ruby object.
* @exception rb_eArgError `v` contains a NUL byte.
* @exception rb_eTypeError `v` is not path-ish.
* @exception rb_eEncCompatError `v` is not path-compatible.
* @post `v` is a path.
*/
#define FilePathValue(v) (RB_GC_GUARD(v) = rb_get_path(v))
/**
* @deprecated This function is an alias of rb_get_path() now. The part that
* did "no_checksafe" was deleted. It remains here because of no
* harm.
*/
VALUE rb_get_path_no_checksafe(VALUE);
/**
* @deprecated This macro is an alias of #FilePathValue now. The part that did
* "String" was deleted. It remains here because of no harm.
*/
#define FilePathStringValue(v) ((v) = rb_get_path(v))
/** @cond INTERNAL_MACRO */
#if defined(HAVE_BUILTIN___BUILTIN_CONSTANT_P) && defined(HAVE_STMT_AND_DECL_IN_EXPR)
# define rb_varargs_argc_check_runtime(argc, vargc) \
(((argc) <= (vargc)) ? (argc) : \
(rb_fatal("argc(%d) exceeds actual arguments(%d)", \
argc, vargc), 0))
# define rb_varargs_argc_valid_p(argc, vargc) \
((argc) == 0 ? (vargc) <= 1 : /* [ruby-core:85266] [Bug #14425] */ \
(argc) == (vargc))
# if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# ifdef HAVE_ATTRIBUTE_ERRORFUNC
ERRORFUNC((" argument length doesn't match"), int rb_varargs_bad_length(int,int));
# else
# define rb_varargs_bad_length(argc, vargc) \
((argc)/rb_varargs_argc_valid_p(argc, vargc))
# endif
# define rb_varargs_argc_check(argc, vargc) \
__builtin_choose_expr(__builtin_constant_p(argc), \
(rb_varargs_argc_valid_p(argc, vargc) ? (argc) : \
rb_varargs_bad_length(argc, vargc)), \
rb_varargs_argc_check_runtime(argc, vargc))
# else
# define rb_varargs_argc_check(argc, vargc) \
rb_varargs_argc_check_runtime(argc, vargc)
# endif
#endif
/** @endcond */
/**
* Queries the name of the passed class.
*
* @param[in] klass An instance of a class.
* @return The name of `klass`.
* @note Return value is managed by our GC. Don't free.
*/
const char *rb_class2name(VALUE klass);
/**
* Queries the name of the class of the passed object.
*
* @param[in] obj Arbitrary ruby object.
* @return The name of the class of `obj`.
* @note Return value is managed by our GC. Don't free.
*/
const char *rb_obj_classname(VALUE obj);
/**
* Inspects an object. It first calls the argument's `#inspect` method, then
* feeds its result string into ::rb_stdout.
*
* This is identical to Ruby level `Kernel#p`, except it takes only one object.
*
* @internal
*
* Above description is in fact inaccurate. This API interfaces with Ractors.
*/
void rb_p(VALUE obj);
/**
* This function is an optimised version of calling `#==`. It checks equality
* between two objects by first doing a fast identity check using using C's
* `==` (same as `BasicObject#equal?`). If that check fails, it calls `#==`
* dynamically. This optimisation actually affects semantics, because when
* `#==` returns false for the same object obj, `rb_equal(obj, obj)` would
* still return true. This happens for `Float::NAN`, where `Float::NAN ==
* Float::NAN` is `false`, but `rb_equal(Float::NAN, Float::NAN)` is `true`.
*
* @param[in] lhs Comparison LHS.
* @param[in] rhs Comparison RHS.
* @retval RUBY_Qtrue They are the same.
* @retval RUBY_Qfalse They are different.
*/
VALUE rb_equal(VALUE lhs, VALUE rhs);
/**
* Identical to rb_require_string(), except it takes C's string instead of
* Ruby's.
*
* @param[in] feature Name of a feature, e.g. `"json"`.
* @exception rb_eLoadError No such feature.
* @exception rb_eRuntimeError `$"` is frozen; unable to push.
* @retval RUBY_Qtrue The feature is loaded for the first time.
* @retval RUBY_Qfalse The feature has already been loaded.
* @post `$"` is updated.
*/
VALUE rb_require(const char *feature);
#include "ruby/intern.h"
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define RUBY_VM 1 /* YARV */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_NATIVETHREAD
/**
* Queries if the thread which calls this function is a ruby's thread.
* "Ruby's" in this context is a thread created using one of our APIs like
* rb_thread_create(). There are distinctions between ruby's and other
* threads. For instance calling ruby methods are allowed only from inside of
* a ruby's thread.
*
* @retval 1 The current thread is a Ruby's thread.
* @retval 0 The current thread is a random thread from outside of Ruby.
*/
int ruby_native_thread_p(void);
/**
* @private
*
* This macro is for internal use. Must be a mistake to place here.
*/
#define InitVM(ext) {void InitVM_##ext(void);InitVM_##ext();}
RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
* Our own locale-insensitive version of `snprintf(3)`. It can also be seen as
* a routine identical to rb_sprintf(), except it writes back to the passed
* buffer instead of allocating a new Ruby object.
*
* @param[out] str Return buffer
* @param[in] n Number of bytes of `str`.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ... Variadic number of contents to format.
* @return Number of bytes that would have been written to `str`, if `n`
* was large enough. Comparing this to `n` can give you insights
* that the buffer is too small or too big. Especially passing 0
* to `n` gives you the exact number of bytes necessary to hold
* the result string without writing anything to anywhere.
* @post `str` holds up to `n-1` bytes of formatted contents (and the
* terminating NUL character.)
*/
int ruby_snprintf(char *str, size_t n, char const *fmt, ...);
RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 0)
/**
* Identical to ruby_snprintf(), except it takes a `va_list`. It can also be
* seen as a routine identical to rb_vsprintf(), except it writes back to the
* passed buffer instead of allocating a new Ruby object.
*
* @param[out] str Return buffer
* @param[in] n Number of bytes of `str`.
* @param[in] fmt A `printf`-like format specifier.
* @param[in] ap Contents to format.
* @return Number of bytes that would have been written to `str`, if `n`
* was large enough. Comparing this to `n` can give you insights
* that the buffer is too small or too big. Especially passing 0
* to `n` gives you the exact number of bytes necessary to hold
* the result string without writing anything to anywhere.
* @post `str` holds up to `n-1` bytes of formatted contents (and the
* terminating NUL character.)
*/
int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
/** @cond INTERNAL_MACRO */
#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
# /* Skip it; clang -pedantic doesn't like the following */
#elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO) && defined(__OPTIMIZE__)
# define rb_yield_values(argc, ...) \
__extension__({ \
const int rb_yield_values_argc = (argc); \
const VALUE rb_yield_values_args[] = {__VA_ARGS__}; \
const int rb_yield_values_nargs = \
(int)(sizeof(rb_yield_values_args) / sizeof(VALUE)); \
rb_yield_values2( \
rb_varargs_argc_check(rb_yield_values_argc, rb_yield_values_nargs), \
rb_yield_values_nargs ? rb_yield_values_args : NULL); \
})
# define rb_funcall(recv, mid, argc, ...) \
__extension__({ \
const int rb_funcall_argc = (argc); \
const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
const int rb_funcall_nargs = \
(int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
rb_funcallv(recv, mid, \
rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
rb_funcall_nargs ? rb_funcall_args : NULL); \
})
#endif
/** @endcond */
#ifndef RUBY_DONT_SUBST
#include "ruby/subst.h"
#endif
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_RUBY_H */
include/ruby/random.h 0000644 00000027006 15040330606 0010603 0 ustar 00 #ifndef RUBY_RANDOM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RANDOM_H 1
/**
* @file
* @date Sat May 7 11:51:14 JST 2016
* @copyright 2007-2020 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*
* This is a set of APIs to roll your own subclass of ::rb_cRandom. An
* illustrative example of such PRNG can be found at
* `ext/-test-/ramdom/loop.c`.
*/
#include "ruby/ruby.h"
/*
* version
* 0: before versioning; deprecated
* 1: added version, flags and init_32bit function
*/
#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR 1
#define RUBY_RANDOM_INTERFACE_VERSION_MINOR 0
#define RUBY_RANDOM_PASTE_VERSION_SUFFIX(x, y, z) x##_##y##_##z
#define RUBY_RANDOM_WITH_VERSION_SUFFIX(name, major, minor) \
RUBY_RANDOM_PASTE_VERSION_SUFFIX(name, major, minor)
#define rb_random_data_type \
RUBY_RANDOM_WITH_VERSION_SUFFIX(rb_random_data_type, \
RUBY_RANDOM_INTERFACE_VERSION_MAJOR, \
RUBY_RANDOM_INTERFACE_VERSION_MINOR)
#define RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER \
{RUBY_RANDOM_INTERFACE_VERSION_MAJOR, RUBY_RANDOM_INTERFACE_VERSION_MINOR}
#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR_MAX 0xff
#define RUBY_RANDOM_INTERFACE_VERSION_MINOR_MAX 0xff
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Base components of the random interface.
*
* @internal
*
* Ideally this could be an empty class if we could assume C++, but in C a
* struct must have at least one field.
*/
struct rb_random_struct {
/** Seed, passed through e.g. `Random.new` */
VALUE seed;
};
typedef struct rb_random_struct rb_random_t; /**< @see ::rb_random_struct */
RBIMPL_ATTR_NONNULL(())
/**
* This is the type of functions called when your random object is initialised.
* Passed buffer is the seed object basically. But in Ruby a number can be
* really big. This type of functions accept such big integers as a series of
* machine words.
*
* @param[out] rng Your random struct to fill in.
* @param[in] buf Seed, maybe converted from a bignum.
* @param[in] len Number of words of `buf`.
* @post `rng` is initialised using the passed seeds.
*/
typedef void rb_random_init_func(rb_random_t *rng, const uint32_t *buf, size_t len);
RBIMPL_ATTR_NONNULL(())
/**
* This is the type of functions called when your random object is initialised.
* Passed data is the seed integer.
*
* @param[out] rng Your random struct to fill in.
* @param[in] data Seed, single word.
* @post `rng` is initialised using the passed seeds.
*/
typedef void rb_random_init_int32_func(rb_random_t *rng, uint32_t data);
RBIMPL_ATTR_NONNULL(())
/**
* This is the type of functions called from your object's `#rand` method.
*
* @param[out] rng Your random struct to extract an integer from.
* @return A random number.
* @post `rng` is consumed somehow.
*/
typedef unsigned int rb_random_get_int32_func(rb_random_t *rng);
RBIMPL_ATTR_NONNULL(())
/**
* This is the type of functions called from your object's `#bytes` method.
*
* @param[out] rng Your random struct to extract an integer from.
* @param[out] buf Return buffer of at least `len` bytes length.
* @param[in] len Number of bytes of `buf`.
* @post `rng` is consumed somehow.
* @post `buf` is filled with random bytes.
*/
typedef void rb_random_get_bytes_func(rb_random_t *rng, void *buf, size_t len);
RBIMPL_ATTR_NONNULL(())
/**
* This is the type of functions called from your object's `#rand` method.
*
* @param[out] rng Your random struct to extract an integer from.
* @param[in] excl Pass nonzero value here to indicate you don't want 1.0.
* @return A random number of range 0.0 to 1.0.
* @post `rng` is consumed somehow.
*/
typedef double rb_random_get_real_func(rb_random_t *rng, int excl);
/** PRNG algorithmic interface, analogous to Ruby level classes. */
typedef struct {
/** Number of bits of seed numbers. */
size_t default_seed_bits;
/**
* Major/minor versions of this interface
*/
struct {
uint8_t major, minor;
} version;
/**
* Reserved flags
*/
uint16_t flags;
/** Function to initialize from uint32_t array. */
rb_random_init_func *init;
/** Function to initialize from single uint32_t. */
rb_random_init_int32_func *init_int32;
/** Function to obtain a random integer. */
rb_random_get_int32_func *get_int32;
/**
* Function to obtain a series of random bytes. If your PRNG have a native
* method to yield arbitrary number of bytes use that to implement this.
* But in case you lack such things, you can do so by using
* rb_rand_bytes_int32()
*
* ```CXX
* extern rb_random_get_int32_func your_get_int32_func;
*
* void
* your_get_byes_func(rb_random_t *rng, void *buf, size_t len)
* {
* rb_rand_bytes_int32(your_get_int32_func, rng, buf, len);
* }
* ```
*/
rb_random_get_bytes_func *get_bytes;
/**
* Function to obtain a random double. If your PRNG have a native method
* to yield a floating point random number use that to implement this. But
* in case you lack such things, you can do so by using
* rb_int_pair_to_real().
*
* ```CXX
* extern rb_random_get_int32_func your_get_int32_func;
*
* void
* your_get_real_func(rb_random_t *rng, int excl)
* {
* auto a = your_get_int32_func(rng);
* auto b = your_get_int32_func(rng);
* return rb_int_pair_to_real(a, b, excl);
* }
* ```
*/
rb_random_get_real_func *get_real;
} rb_random_interface_t;
/**
* This utility macro defines 4 functions named prefix_init, prefix_init_int32,
* prefix_get_int32, prefix_get_bytes.
*/
#define RB_RANDOM_INTERFACE_DECLARE(prefix) \
static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
static void prefix##_init_int32(rb_random_t *, uint32_t); \
static unsigned int prefix##_get_int32(rb_random_t *); \
static void prefix##_get_bytes(rb_random_t *, void *, size_t)
/**
* Identical to #RB_RANDOM_INTERFACE_DECLARE except it also declares
* prefix_get_real.
*/
#define RB_RANDOM_INTERFACE_DECLARE_WITH_REAL(prefix) \
RB_RANDOM_INTERFACE_DECLARE(prefix); \
static double prefix##_get_real(rb_random_t *, int)
/**
* This utility macro expands to the names declared using
* #RB_RANDOM_INTERFACE_DECLARE. Expected to be used inside of a
* ::rb_random_interface_t initialiser:
*
* ```CXX
* RB_RANDOM_INTERFACE_DECLARE(foo);
*
* static inline constexpr rb_random_interface_t foo_interface = {
* 32768, // bits
* RB_RANDOM_INTERFACE_DEFINE(foo),
* };
* ```
*/
#define RB_RANDOM_INTERFACE_DEFINE(prefix) \
RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER, 0, \
prefix##_init, \
prefix##_init_int32, \
prefix##_get_int32, \
prefix##_get_bytes
/**
* Identical to #RB_RANDOM_INTERFACE_DEFINE except it also defines
* prefix_get_real.
*/
#define RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(prefix) \
RB_RANDOM_INTERFACE_DEFINE(prefix), \
prefix##_get_real
#define RB_RANDOM_DEFINE_INIT_INT32_FUNC(prefix) \
static void prefix##_init_int32(rb_random_t *rnd, uint32_t data) \
{ \
prefix##_init(rnd, &data, 1); \
}
#if defined _WIN32 && !defined __CYGWIN__
typedef rb_data_type_t rb_random_data_type_t;
# define RB_RANDOM_PARENT 0
#else
/** This is the type of ::rb_random_data_type. */
typedef const rb_data_type_t rb_random_data_type_t;
/**
* This utility macro can be used when you define your own PRNG type:
*
* ```CXX
* static inline constexpr rb_random_interface_t your_if = {
* 0, RB_RANDOM_INTERFACE_DEFINE(your),
* };
*
* static inline constexpr rb_random_data_type_t your_prng_type = {
* "your PRNG",
* { rb_random_mark, },
* RB_RANDOM_PARENT, // <<-- HERE
* &your_if,
* 0,
* }
* ```
*/
# define RB_RANDOM_PARENT &rb_random_data_type
#endif
/**
* This macro is expected to be called exactly once at the beginning of a
* program, possibly from inside of your `Init_Foo()` function. Depending on
* platforms #RB_RANDOM_PARENT can require a fixup. This routine does that
* when necessary.
*/
#define RB_RANDOM_DATA_INIT_PARENT(random_data) \
rbimpl_random_data_init_parent(&random_data)
/**
* This is the implementation of ::rb_data_type_struct::dmark for
* ::rb_random_data_type. In case your PRNG does not involve Ruby objects at
* all (which is quite likely), you can simply reuse it.
*
* @param[out] ptr Target to mark, which is a ::rb_random_t this case.
*/
void rb_random_mark(void *ptr);
/**
* Initialises an allocated ::rb_random_t instance. Call it from your own
* initialiser appropriately.
*
* @param[out] rnd Your PRNG's base part.
* @post `rnd` is filled with an initial state.
*/
void rb_random_base_init(rb_random_t *rnd);
/**
* Generates a 64 bit floating point number by concatenating two 32bit unsigned
* integers.
*
* @param[in] a Most significant 32 bits of the result.
* @param[in] b Least significant 32 bits of the result.
* @param[in] excl Whether the result should exclude 1.0 or not.
* @return A double, whose range is either `[0, 1)` or `[0, 1]`.
* @see ::rb_random_interface_t::get_real()
*
* @internal
*
* This in fact has nothing to do with PRNGs.
*/
double rb_int_pair_to_real(uint32_t a, uint32_t b, int excl);
/**
* Repeatedly calls the passed function over and over again until the passed
* buffer is filled with random bytes.
*
* @param[in] func Generator function.
* @param[out] prng Passed as-is to `func`.
* @param[out] buff Return buffer.
* @param[in] size Number of words of `buff`.
* @post `buff` is filled with random bytes.
* @post `prng` is updated by `func`.
* @see ::rb_random_interface_t::get_bytes()
*/
void rb_rand_bytes_int32(rb_random_get_int32_func *func, rb_random_t *prng, void *buff, size_t size);
/**
* The data that holds the backend type of ::rb_cRandom. Used as your PRNG's
* ::rb_data_type_struct::parent.
*/
RUBY_EXTERN const rb_data_type_t rb_random_data_type;
RBIMPL_SYMBOL_EXPORT_END()
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
* Queries the interface of the passed random object.
*
* @param[in] obj An instance (of a subclass) of ::rb_cRandom.
* @return Its corresponding ::rb_random_interface_t interface.
*/
static inline const rb_random_interface_t *
rb_rand_if(VALUE obj)
{
RBIMPL_ASSERT_OR_ASSUME(RTYPEDDATA_P(obj));
const struct rb_data_type_struct *t = RTYPEDDATA_TYPE(obj);
const void *ret = t->data;
return RBIMPL_CAST((const rb_random_interface_t *)ret);
}
RBIMPL_ATTR_NOALIAS()
/**
* @private
*
* This is an implementation detail of #RB_RANDOM_DATA_INIT_PARENT. People
* don't use it directly.
*
* @param[out] random_data Region to fill.
* @post ::rb_random_data_type is filled appropriately.
*/
static inline void
rbimpl_random_data_init_parent(rb_random_data_type_t *random_data)
{
#if defined _WIN32 && !defined __CYGWIN__
random_data->parent = &rb_random_data_type;
#endif
}
#endif /* RUBY_RANDOM_H */
include/ruby/atomic.h 0000644 00000064271 15040330606 0010604 0 ustar 00 #ifndef RUBY_ATOMIC_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ATOMIC_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Atomic operations
*
* Basically, if we could assume either C11 or C++11, these macros are just
* redundant. Sadly we cannot. We have to do them ourselves.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h> /* size_t */
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
#if RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
# pragma intrinsic(_InterlockedOr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
# include <atomic.h>
#endif
#include "ruby/assert.h"
#include "ruby/backward/2/limits.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/value.h"
#include "ruby/internal/static_assert.h"
#include "ruby/internal/stdbool.h"
/*
* Asserts that your environment supports more than one atomic types. These
* days systems tend to have such property (C11 was a standard of decades ago,
* right?) but we still support older ones.
*/
#if defined(__DOXYGEN__) || defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
# define RUBY_ATOMIC_GENERIC_MACRO 1
#endif
/**
* Type that is eligible for atomic operations. Depending on your host
* platform you might have more than one such type, but we choose one of them
* anyways.
*/
#if defined(__DOXYGEN__)
using rb_atomic_t = std::atomic<unsigned>;
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
typedef unsigned int rb_atomic_t;
#elif defined(HAVE_GCC_SYNC_BUILTINS)
typedef unsigned int rb_atomic_t;
#elif defined(_WIN32)
typedef LONG rb_atomic_t;
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
typedef unsigned int rb_atomic_t;
#else
# error No atomic operation found
#endif
/**
* Atomically replaces the value pointed by `var` with the result of addition
* of `val` to the old value of `var`.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to add.
* @return What was stored in `var` before the addition.
* @post `var` holds `var + val`.
*/
#define RUBY_ATOMIC_FETCH_ADD(var, val) rbimpl_atomic_fetch_add(&(var), (val))
/**
* Atomically replaces the value pointed by `var` with the result of
* subtraction of `val` to the old value of `var`.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to subtract.
* @return What was stored in `var` before the subtraction.
* @post `var` holds `var - val`.
*/
#define RUBY_ATOMIC_FETCH_SUB(var, val) rbimpl_atomic_fetch_sub(&(var), (val))
/**
* Atomically replaces the value pointed by `var` with the result of
* bitwise OR between `val` and the old value of `var`.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to mix.
* @return void
* @post `var` holds `var | val`.
* @note For portability, this macro can return void.
*/
#define RUBY_ATOMIC_OR(var, val) rbimpl_atomic_or(&(var), (val))
/**
* Atomically replaces the value pointed by `var` with `val`. This is just an
* assignment, but you can additionally know the previous value.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to set.
* @return What was stored in `var` before the assignment.
* @post `var` holds `val`.
*/
#define RUBY_ATOMIC_EXCHANGE(var, val) rbimpl_atomic_exchange(&(var), (val))
/**
* Atomic compare-and-swap. This stores `val` to `var` if and only if the
* assignment changes the value of `var` from `oldval` to `newval`. You can
* detect whether the assignment happened or not using the return value.
*
* @param var A variable of ::rb_atomic_t.
* @param oldval Expected value of `var` before the assignment.
* @param newval What you want to store at `var`.
* @retval oldval Successful assignment (`var` is now `newval`).
* @retval otherwise Something else is at `var`; not updated.
*/
#define RUBY_ATOMIC_CAS(var, oldval, newval) \
rbimpl_atomic_cas(&(var), (oldval), (newval))
/**
* Identical to #RUBY_ATOMIC_EXCHANGE, except for the return type.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to set.
* @return void
* @post `var` holds `val`.
*/
#define RUBY_ATOMIC_SET(var, val) rbimpl_atomic_set(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_FETCH_ADD, except for the return type.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to add.
* @return void
* @post `var` holds `var + val`.
*/
#define RUBY_ATOMIC_ADD(var, val) rbimpl_atomic_add(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_FETCH_SUB, except for the return type.
*
* @param var A variable of ::rb_atomic_t.
* @param val Value to subtract.
* @return void
* @post `var` holds `var - val`.
*/
#define RUBY_ATOMIC_SUB(var, val) rbimpl_atomic_sub(&(var), (val))
/**
* Atomically increments the value pointed by `var`.
*
* @param var A variable of ::rb_atomic_t.
* @return void
* @post `var` holds `var + 1`.
*/
#define RUBY_ATOMIC_INC(var) rbimpl_atomic_inc(&(var))
/**
* Atomically decrements the value pointed by `var`.
*
* @param var A variable of ::rb_atomic_t.
* @return void
* @post `var` holds `var - 1`.
*/
#define RUBY_ATOMIC_DEC(var) rbimpl_atomic_dec(&(var))
/**
* Identical to #RUBY_ATOMIC_INC, except it expects its argument is `size_t`.
* There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `size_t`.
* @return void
* @post `var` holds `var + 1`.
*/
#define RUBY_ATOMIC_SIZE_INC(var) rbimpl_atomic_size_inc(&(var))
/**
* Identical to #RUBY_ATOMIC_DEC, except it expects its argument is `size_t`.
* There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `size_t`.
* @return void
* @post `var` holds `var - 1`.
*/
#define RUBY_ATOMIC_SIZE_DEC(var) rbimpl_atomic_size_dec(&(var))
/**
* Identical to #RUBY_ATOMIC_EXCHANGE, except it expects its arguments are
* `size_t`. There are cases where ::rb_atomic_t is 32bit while `size_t` is
* 64bit. This should be used for size related operations to support such
* platforms.
*
* @param var A variable of `size_t`.
* @param val Value to set.
* @return What was stored in `var` before the assignment.
* @post `var` holds `val`.
*/
#define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) \
rbimpl_atomic_size_exchange(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `size_t`.
* There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `size_t`.
* @param oldval Expected value of `var` before the assignment.
* @param newval What you want to store at `var`.
* @retval oldval Successful assignment (`var` is now `newval`).
* @retval otherwise Something else is at `var`; not updated.
*/
#define RUBY_ATOMIC_SIZE_CAS(var, oldval, newval) \
rbimpl_atomic_size_cas(&(var), (oldval), (newval))
/**
* Identical to #RUBY_ATOMIC_ADD, except it expects its arguments are `size_t`.
* There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `size_t`.
* @param val Value to add.
* @return void
* @post `var` holds `var + val`.
*/
#define RUBY_ATOMIC_SIZE_ADD(var, val) rbimpl_atomic_size_add(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_SUB, except it expects its arguments are `size_t`.
* There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `size_t`.
* @param val Value to subtract.
* @return void
* @post `var` holds `var - val`.
*/
#define RUBY_ATOMIC_SIZE_SUB(var, val) rbimpl_atomic_size_sub(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_EXCHANGE, except it expects its arguments are
* `void*`. There are cases where ::rb_atomic_t is 32bit while `void*` is
* 64bit. This should be used for pointer related operations to support such
* platforms.
*
* @param var A variable of `void *`.
* @param val Value to set.
* @return What was stored in `var` before the assignment.
* @post `var` holds `val`.
*
* @internal
*
* :FIXME: this `(void*)` cast is evil! However `void*` is incompatible with
* some pointers, most notably function pointers.
*/
#define RUBY_ATOMIC_PTR_EXCHANGE(var, val) \
RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))
/**
* Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.
* There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `void*`.
* @param oldval Expected value of `var` before the assignment.
* @param newval What you want to store at `var`.
* @retval oldval Successful assignment (`var` is now `newval`).
* @retval otherwise Something else is at `var`; not updated.
*/
#define RUBY_ATOMIC_PTR_CAS(var, oldval, newval) \
RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (oldval), (newval)))
/**
* Identical to #RUBY_ATOMIC_EXCHANGE, except it expects its arguments are
* ::VALUE. There are cases where ::rb_atomic_t is 32bit while ::VALUE is
* 64bit. This should be used for pointer related operations to support such
* platforms.
*
* @param var A variable of ::VALUE.
* @param val Value to set.
* @return What was stored in `var` before the assignment.
* @post `var` holds `val`.
*/
#define RUBY_ATOMIC_VALUE_EXCHANGE(var, val) \
rbimpl_atomic_value_exchange(&(var), (val))
/**
* Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are ::VALUE.
* There are cases where ::rb_atomic_t is 32bit while ::VALUE is 64bit. This
* should be used for size related operations to support such platforms.
*
* @param var A variable of `void*`.
* @param oldval Expected value of `var` before the assignment.
* @param newval What you want to store at `var`.
* @retval oldval Successful assignment (`var` is now `newval`).
* @retval otherwise Something else is at `var`; not updated.
*/
#define RUBY_ATOMIC_VALUE_CAS(var, oldval, newval) \
rbimpl_atomic_value_cas(&(var), (oldval), (newval))
/** @cond INTERNAL_MACRO */
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_fetch_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
return __atomic_fetch_add(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_fetch_and_add(ptr, val);
#elif defined(_WIN32)
return InterlockedExchangeAdd(ptr, val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
/*
* `atomic_add_int_nv` takes its second argument as `int`! Meanwhile our
* `rb_atomic_t` is unsigned. We cannot pass `val` as-is. We have to
* manually check integer overflow.
*/
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
return atomic_add_int_nv(ptr, val) - val;
#else
# error Unsupported platform.
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
/*
* GCC on amd64 is smart enough to detect this `__atomic_add_fetch`'s
* return value is not used, then compiles it into single `LOCK ADD`
* instruction.
*/
__atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
__sync_add_and_fetch(ptr, val);
#elif defined(_WIN32)
/*
* `InterlockedExchangeAdd` is `LOCK XADD`. It seems there also is
* `_InterlockedAdd` intrinsic in ARM Windows but not for x86? Sticking to
* `InterlockedExchangeAdd` for better portability.
*/
InterlockedExchangeAdd(ptr, val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
/* Ditto for `atomic_add_int_nv`. */
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
atomic_add_int(ptr, val);
#else
# error Unsupported platform.
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_add(volatile size_t *ptr, size_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
__sync_add_and_fetch(ptr, val);
#elif defined(_WIN32) && defined(_M_AMD64)
/* Ditto for `InterlockeExchangedAdd`. */
InterlockedExchangeAdd64(ptr, val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
/* Ditto for `atomic_add_int_nv`. */
RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
atomic_add_long(ptr, val);
#else
RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
rbimpl_atomic_add(tmp, val);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_inc(volatile rb_atomic_t *ptr)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
rbimpl_atomic_add(ptr, 1);
#elif defined(_WIN32)
InterlockedIncrement(ptr);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_inc_uint(ptr);
#else
rbimpl_atomic_add(ptr, 1);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_inc(volatile size_t *ptr)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
rbimpl_atomic_size_add(ptr, 1);
#elif defined(_WIN32) && defined(_M_AMD64)
InterlockedIncrement64(ptr);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
atomic_inc_ulong(ptr);
#else
rbimpl_atomic_size_add(ptr, 1);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_fetch_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
return __atomic_fetch_sub(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_fetch_and_sub(ptr, val);
#elif defined(_WIN32)
/* rb_atomic_t is signed here! Safe to do `-val`. */
return InterlockedExchangeAdd(ptr, -val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
/* Ditto for `rbimpl_atomic_fetch_add`. */
const signed neg = -1;
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
return atomic_add_int_nv(ptr, neg * val) + val;
#else
# error Unsupported platform.
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
__sync_sub_and_fetch(ptr, val);
#elif defined(_WIN32)
InterlockedExchangeAdd(ptr, -val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
const signed neg = -1;
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
atomic_add_int(ptr, neg * val);
#else
# error Unsupported platform.
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_sub(volatile size_t *ptr, size_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
__sync_sub_and_fetch(ptr, val);
#elif defined(_WIN32) && defined(_M_AMD64)
const ssize_t neg = -1;
InterlockedExchangeAdd64(ptr, neg * val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
const signed neg = -1;
RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
atomic_add_long(ptr, neg * val);
#else
RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
rbimpl_atomic_sub(tmp, val);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_dec(volatile rb_atomic_t *ptr)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
rbimpl_atomic_sub(ptr, 1);
#elif defined(_WIN32)
InterlockedDecrement(ptr);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_dec_uint(ptr);
#else
rbimpl_atomic_sub(ptr, 1);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_dec(volatile size_t *ptr)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
rbimpl_atomic_size_sub(ptr, 1);
#elif defined(_WIN32) && defined(_M_AMD64)
InterlockedDecrement64(ptr);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
atomic_dec_ulong(ptr);
#else
rbimpl_atomic_size_sub(ptr, 1);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_or(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_or_fetch(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
__sync_or_and_fetch(ptr, val);
#elif RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
_InterlockedOr(ptr, val);
#elif defined(_WIN32) && defined(__GNUC__)
/* This was for old MinGW. Maybe not needed any longer? */
__asm__(
"lock\n\t"
"orl\t%1, %0"
: "=m"(ptr)
: "Ir"(val));
#elif defined(_WIN32) && defined(_M_IX86)
__asm mov eax, ptr;
__asm mov ecx, val;
__asm lock or [eax], ecx;
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_or_uint(ptr, val);
#else
# error Unsupported platform.
#endif
}
/* Nobody uses this but for theoretical backwards compatibility... */
#if RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
static inline rb_atomic_t
rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
{
return rbimpl_atomic_or(var, val);
}
#endif
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_exchange(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
return __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_lock_test_and_set(ptr, val);
#elif defined(_WIN32)
return InterlockedExchange(ptr, val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
return atomic_swap_uint(ptr, val);
#else
# error Unsupported platform.
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline size_t
rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
return __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST);
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_lock_test_and_set(ptr, val);
#elif defined(_WIN32) && defined(_M_AMD64)
return InterlockedExchange64(ptr, val);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
return atomic_swap_ulong(ptr, val);
#else
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
const rb_atomic_t ret = rbimpl_atomic_exchange(tmp, val);
return RBIMPL_CAST((size_t)ret);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void *
rbimpl_atomic_ptr_exchange(void *volatile *ptr, const void *val)
{
#if 0
#elif defined(InterlockedExchangePointer)
/* const_cast */
PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
PVOID pval = RBIMPL_CAST((PVOID)val);
return InterlockedExchangePointer(pptr, pval);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
return atomic_swap_ptr(ptr, RBIMPL_CAST((void *)val));
#else
RBIMPL_STATIC_ASSERT(sizeof_voidp, sizeof *ptr == sizeof(size_t));
const size_t sval = RBIMPL_CAST((size_t)val);
volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
return RBIMPL_CAST((void *)sret);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
{
RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t));
const size_t sval = RBIMPL_CAST((size_t)val);
volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
return RBIMPL_CAST((VALUE)sret);
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_set(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_store_n(ptr, val, __ATOMIC_SEQ_CST);
#else
/* Maybe std::atomic<rb_atomic_t>::store can be faster? */
rbimpl_atomic_exchange(ptr, val);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_cas(volatile rb_atomic_t *ptr, rb_atomic_t oldval, rb_atomic_t newval)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_compare_exchange_n(
ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return oldval;
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
return InterlockedCompareExchange(ptr, newval, oldval);
#elif defined(_WIN32)
PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
PVOID pold = RBIMPL_CAST((PVOID)oldval);
PVOID pnew = RBIMPL_CAST((PVOID)newval);
PVOID pret = InterlockedCompareExchange(pptr, pnew, pold);
return RBIMPL_CAST((rb_atomic_t)pret);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
return atomic_cas_uint(ptr, oldval, newval);
#else
# error Unsupported platform.
#endif
}
/* Nobody uses this but for theoretical backwards compatibility... */
#if RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
static inline rb_atomic_t
rb_w32_atomic_cas(volatile rb_atomic_t *var, rb_atomic_t oldval, rb_atomic_t newval)
{
return rbimpl_atomic_cas(var, oldval, newval);
}
#endif
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline size_t
rbimpl_atomic_size_cas(volatile size_t *ptr, size_t oldval, size_t newval)
{
#if 0
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
__atomic_compare_exchange_n(
ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return oldval;
#elif defined(HAVE_GCC_SYNC_BUILTINS)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif defined(_WIN32) && defined(_M_AMD64)
return InterlockedCompareExchange64(ptr, newval, oldval);
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
return atomic_cas_ulong(ptr, oldval, newval);
#else
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));
volatile rb_atomic_t *tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
return rbimpl_atomic_cas(tmp, oldval, newval);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void *
rbimpl_atomic_ptr_cas(void **ptr, const void *oldval, const void *newval)
{
#if 0
#elif defined(InterlockedExchangePointer)
/* ... Can we say that InterlockedCompareExchangePtr surly exists when
* InterlockedExchangePointer is defined? Seems so but...?*/
PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
PVOID pold = RBIMPL_CAST((PVOID)oldval);
PVOID pnew = RBIMPL_CAST((PVOID)newval);
return InterlockedCompareExchangePointer(pptr, pnew, pold);
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
void *pold = RBIMPL_CAST((void *)oldval);
void *pnew = RBIMPL_CAST((void *)newval);
return atomic_cas_ptr(ptr, pold, pnew);
#else
RBIMPL_STATIC_ASSERT(sizeof_voidp, sizeof *ptr == sizeof(size_t));
const size_t snew = RBIMPL_CAST((size_t)newval);
const size_t sold = RBIMPL_CAST((size_t)oldval);
volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
return RBIMPL_CAST((void *)sret);
#endif
}
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_cas(volatile VALUE *ptr, VALUE oldval, VALUE newval)
{
RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t));
const size_t snew = RBIMPL_CAST((size_t)newval);
const size_t sold = RBIMPL_CAST((size_t)oldval);
volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
return RBIMPL_CAST((VALUE)sret);
}
/** @endcond */
#endif /* RUBY_ATOMIC_H */
include/ruby/regex.h 0000644 00000001763 15040330606 0010437 0 ustar 00 #ifndef ONIGURUMA_REGEX_H /*-*-C++-*-vi:se ft=cpp:*/
#define ONIGURUMA_REGEX_H 1
/**
* @author $Author$
* @copyright Copyright (C) 1993-2007 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif
#ifdef RUBY
#include "ruby/oniguruma.h"
#else
#include "oniguruma.h"
#endif
RUBY_SYMBOL_EXPORT_BEGIN
#ifndef ONIG_RUBY_M17N
ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding;
#define mbclen(p,e,enc) rb_enc_mbclen((p),(e),(enc))
#endif /* ifndef ONIG_RUBY_M17N */
RUBY_SYMBOL_EXPORT_END
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
} /* extern "C" { */
#endif
#endif /* ONIGURUMA_REGEX_H */
include/ruby/fiber/scheduler.h 0000644 00000034263 15040330607 0012374 0 ustar 00 #ifndef RUBY_FIBER_SCHEDULER_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_FIBER_SCHEDULER_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @brief Scheduler APIs.
*/
#include "ruby/internal/config.h"
#include <errno.h>
#ifdef STDC_HEADERS
#include <stddef.h> /* size_t */
#endif
#include "ruby/ruby.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/arithmetic.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
#define RUBY_FIBER_SCHEDULER_VERSION 2
struct timeval;
/**
* Wrap a `ssize_t` and `int errno` into a single `VALUE`. This interface should
* be used to safely capture results from system calls like `read` and `write`.
*
* You should use `rb_fiber_scheduler_io_result_apply` to unpack the result of
* this value and update `int errno`.
*
* You should not directly try to interpret the result value as it is considered
* an opaque representation. However, the general representation is an integer
* in the range of `[-int errno, size_t size]`. Linux generally restricts the
* result of system calls like `read` and `write` to `<= 2^31` which means this
* will typically fit within a single FIXNUM.
*
* @param[in] result The result of the system call.
* @param[in] error The value of `errno`.
* @return A `VALUE` which contains the result and/or errno.
*/
static inline VALUE
rb_fiber_scheduler_io_result(ssize_t result, int error)
{
if (result == -1) {
return RB_INT2NUM(-error);
}
else {
return RB_SIZE2NUM(result);
}
}
/**
* Apply an io result to the local thread, returning the value of the original
* system call that created it and updating `int errno`.
*
* You should not directly try to interpret the result value as it is considered
* an opaque representation.
*
* @param[in] result The `VALUE` which contains an errno and/or result size.
* @post Updates `int errno` with the value if negative.
* @return The original result of the system call.
*/
static inline ssize_t
rb_fiber_scheduler_io_result_apply(VALUE result)
{
if (RB_FIXNUM_P(result) && RB_NUM2INT(result) < 0) {
errno = -RB_NUM2INT(result);
return -1;
}
else {
return RB_NUM2SIZE(result);
}
}
/**
* Queries the current scheduler of the current thread that is calling this
* function.
*
* @retval RUBY_Qnil No scheduler has been set so far to this thread (which
* is the default).
* @retval otherwise The scheduler that was last set for the current thread
* with rb_fiber_scheduler_set().
*/
VALUE rb_fiber_scheduler_get(void);
/**
* Destructively assigns the passed scheduler to that of the current thread
* that is calling this function. If the scheduler is set, non-blocking fibers
* (created by `Fiber.new` with `blocking: false`, or by `Fiber.schedule`) call
* that scheduler's hook methods on potentially blocking operations, and the
* current thread will call scheduler's `#close` method on finalisation
* (allowing the scheduler to properly manage all non-finished fibers).
* `scheduler` can be an object of any class corresponding to
* `Fiber::SchedulerInterface`. Its implementation is up to the user.
*
* @param[in] scheduler The scheduler to set.
* @exception rb_eArgError `scheduler` does not conform the interface.
* @post Current thread's scheduler is `scheduler`.
*/
VALUE rb_fiber_scheduler_set(VALUE scheduler);
/**
* Identical to rb_fiber_scheduler_get(), except it also returns ::RUBY_Qnil in
* case of a blocking fiber. As blocking fibers do not participate schedulers'
* scheduling this function can be handy.
*
* @retval RUBY_Qnil No scheduler is in effect.
* @retval otherwise The scheduler that is in effect, if any.
*/
VALUE rb_fiber_scheduler_current(void);
/**
* Identical to rb_fiber_scheduler_current(), except it queries for that of the
* passed thread instead of the implicit current one.
*
* @param[in] thread Target thread.
* @exception rb_eTypeError `thread` is not a thread.
* @retval RUBY_Qnil No scheduler is in effect in `thread`.
* @retval otherwise The scheduler that is in effect in `thread`.
*/
VALUE rb_fiber_scheduler_current_for_thread(VALUE thread);
/**
* Converts the passed timeout to an expression that rb_fiber_scheduler_block()
* etc. expects.
*
* @param[in] timeout A duration (can be `NULL`).
* @retval RUBY_Qnil No timeout (blocks indefinitely).
* @retval otherwise A timeout object.
*/
VALUE rb_fiber_scheduler_make_timeout(struct timeval *timeout);
/**
* Closes the passed scheduler object. This expects the scheduler to wait for
* all fibers. Thus the scheduler's main loop tends to start here.
*
* @param[in] scheduler Target scheduler.
* @return What `scheduler.close` returns.
*/
VALUE rb_fiber_scheduler_close(VALUE scheduler);
/**
* Non-blocking `sleep`. Depending on scheduler implementation, this for
* instance switches to another fiber etc.
*
* @param[in] scheduler Target scheduler.
* @param[in] duration Passed as-is to `scheduler.kernel_sleep`.
* @return What `scheduler.kernel_sleep` returns.
*/
VALUE rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);
/**
* Identical to rb_fiber_scheduler_kernel_sleep(), except it can pass multiple
* arguments.
*
* @param[in] scheduler Target scheduler.
* @param[in] argc Number of objects of `argv`.
* @param[in] argv Passed as-is to `scheduler.kernel_sleep`
* @return What `scheduler.kernel_sleep` returns.
*/
VALUE rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);
/* Description TBW */
#if 0
VALUE rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception, VALUE message);
VALUE rb_fiber_scheduler_timeout_afterv(VALUE scheduler, int argc, VALUE * argv);
int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
#endif
/**
* Non-blocking `waitpid`. Depending on scheduler implementation, this for
* instance switches to another fiber etc.
*
* @param[in] scheduler Target scheduler.
* @param[in] pid Process ID to wait.
* @param[in] flags Wait flags, e.g. `WUNTRACED`.
* @return What `scheduler.process_wait` returns.
*/
VALUE rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
/**
* Non-blocking wait for the passed "blocker", which is for instance
* `Thread.join` or `Mutex.lock`. Depending on scheduler implementation, this
* for instance switches to another fiber etc.
*
* @param[in] scheduler Target scheduler.
* @param[in] blocker What blocks the current fiber.
* @param[in] timeout Numeric timeout.
* @return What `scheduler.block` returns.
*/
VALUE rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
/**
* Wakes up a fiber previously blocked using rb_fiber_scheduler_block().
*
* @param[in] scheduler Target scheduler.
* @param[in] blocker What was awaited for.
* @param[in] fiber What to unblock.
* @return What `scheduler.unblock` returns.
*/
VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
/**
* Non-blocking version of rb_io_wait(). Depending on scheduler
* implementation, this for instance switches to another fiber etc.
*
* The "events" here is a Ruby level integer, which is an OR-ed value of
* `IO::READABLE`, `IO::WRITABLE`, and `IO::PRIORITY`.
*
* @param[in] scheduler Target scheduler.
* @param[in] io An io object to wait.
* @param[in] events An integer set of interests.
* @param[in] timeout Numeric timeout.
* @return What `scheduler.io_wait` returns.
*/
VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
/**
* Non-blocking wait until the passed IO is ready for reading. This is a
* special case of rb_fiber_scheduler_io_wait(), where the interest is
* `IO::READABLE` and timeout is never.
*
* @param[in] scheduler Target scheduler.
* @param[in] io An io object to wait.
* @return What `scheduler.io_wait` returns.
*/
VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
/**
* Non-blocking wait until the passed IO is ready for writing. This is a
* special case of rb_fiber_scheduler_io_wait(), where the interest is
* `IO::WRITABLE` and timeout is never.
*
* @param[in] scheduler Target scheduler.
* @param[in] io An io object to wait.
* @return What `scheduler.io_wait` returns.
*/
VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
/**
* Non-blocking version of `IO.select`.
*
* It's possible that this will be emulated using a thread, so you should not
* rely on it for high performance.
*
* @param[in] scheduler Target scheduler.
* @param[in] readables An array of readable objects.
* @param[in] writables An array of writable objects.
* @param[in] exceptables An array of objects that might encounter exceptional conditions.
* @param[in] timeout Numeric timeout or nil.
* @return What `scheduler.io_select` returns, normally a 3-tuple of arrays of ready objects.
*/
VALUE rb_fiber_scheduler_io_select(VALUE scheduler, VALUE readables, VALUE writables, VALUE exceptables, VALUE timeout);
/**
* Non-blocking version of `IO.select`, `argv` variant.
*/
VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv);
/**
* Non-blocking read from the passed IO.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to read from.
* @param[out] buffer Return buffer.
* @param[in] length Requested number of bytes to read.
* @param[in] offset The offset in the buffer to read to.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns `[-errno, size]`.
*/
VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
/**
* Non-blocking write to the passed IO.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to write to.
* @param[in] buffer What to write.
* @param[in] length Number of bytes to write.
* @param[in] offset The offset in the buffer to write from.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns `[-errno, size]`.
*/
VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
/**
* Non-blocking read from the passed IO at the specified offset.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to read from.
* @param[in] from The offset in the given IO to read the data from.
* @param[out] buffer The buffer to read the data to.
* @param[in] length Requested number of bytes to read.
* @param[in] offset The offset in the buffer to read to.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns.
*/
VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
/**
* Non-blocking write to the passed IO at the specified offset.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to write to.
* @param[in] from The offset in the given IO to write the data to.
* @param[in] buffer The buffer to write the data from.
* @param[in] length Number of bytes to write.
* @param[in] offset The offset in the buffer to write from.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns.
*/
VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
/**
* Non-blocking read from the passed IO using a native buffer.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to read from.
* @param[out] buffer Return buffer.
* @param[in] size Size of the return buffer.
* @param[in] length Requested number of bytes to read.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns.
*/
VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *buffer, size_t size, size_t length);
/**
* Non-blocking write to the passed IO using a native buffer.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to write to.
* @param[in] buffer What to write.
* @param[in] size Size of the buffer.
* @param[in] length Number of bytes to write.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns.
*/
VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *buffer, size_t size, size_t length);
/**
* Non-blocking close the given IO.
*
* @param[in] scheduler Target scheduler.
* @param[in] io An io object to close.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_close`.
* @return otherwise What `scheduler.io_close` returns.
*/
VALUE rb_fiber_scheduler_io_close(VALUE scheduler, VALUE io);
/**
* Non-blocking DNS lookup.
*
* @param[in] scheduler Target scheduler.
* @param[in] hostname A host name to query.
* @retval RUBY_Qundef `scheduler` doesn't have `#address_resolve`.
* @return otherwise What `scheduler.address_resolve` returns.
*/
VALUE rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname);
/**
* Create and schedule a non-blocking fiber.
*
*/
VALUE rb_fiber_scheduler_fiber(VALUE scheduler, int argc, VALUE *argv, int kw_splat);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_FIBER_SCHEDULER_H */
include/ruby/io/buffer.h 0000644 00000006424 15040330607 0011205 0 ustar 00 #ifndef RUBY_IO_BUFFER_H
#define RUBY_IO_BUFFER_H
/**
* @file
* @author Samuel Williams
* @date Fri 2 Jul 2021 16:29:01 NZST
* @copyright Copyright (C) 2021 Samuel Williams
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#pragma once
#include "ruby/ruby.h"
#include "ruby/internal/config.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
// WARNING: This entire interface is experimental and may change in the future!
#define RB_IO_BUFFER_EXPERIMENTAL 1
#define RUBY_IO_BUFFER_VERSION 2
RUBY_EXTERN VALUE rb_cIOBuffer;
RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE;
RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE;
enum rb_io_buffer_flags {
// The memory in the buffer is owned by someone else.
// More specifically, it means that someone else owns the buffer and we shouldn't try to resize it.
RB_IO_BUFFER_EXTERNAL = 1,
// The memory in the buffer is allocated internally.
RB_IO_BUFFER_INTERNAL = 2,
// The memory in the buffer is mapped.
// A non-private mapping is marked as external.
RB_IO_BUFFER_MAPPED = 4,
// A mapped buffer that is also shared.
RB_IO_BUFFER_SHARED = 8,
// The buffer is locked and cannot be resized.
// More specifically, it means we can't change the base address or size.
// A buffer is typically locked before a system call that uses the data.
RB_IO_BUFFER_LOCKED = 32,
// The buffer mapping is private and will not impact other processes or the underlying file.
RB_IO_BUFFER_PRIVATE = 64,
// The buffer is read-only and cannot be modified.
RB_IO_BUFFER_READONLY = 128
};
enum rb_io_buffer_endian {
RB_IO_BUFFER_LITTLE_ENDIAN = 4,
RB_IO_BUFFER_BIG_ENDIAN = 8,
#if defined(WORDS_BIGENDIAN)
RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN,
#else
RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN,
#endif
RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN
};
VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags);
VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags flags);
VALUE rb_io_buffer_lock(VALUE self);
VALUE rb_io_buffer_unlock(VALUE self);
int rb_io_buffer_try_unlock(VALUE self);
VALUE rb_io_buffer_free(VALUE self);
int rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size);
void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size);
void rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size);
VALUE rb_io_buffer_transfer(VALUE self);
void rb_io_buffer_resize(VALUE self, size_t size);
void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length);
// The length is the minimum required length.
VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length, size_t offset);
VALUE rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length, size_t offset);
VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_IO_BUFFER_H */
include/ruby/missing.h 0000644 00000015261 15040330607 0010775 0 ustar 00 #ifndef RUBY_MISSING_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_MISSING_H 1
/**
* @author $Author$
* @date Sat May 11 23:46:03 JST 2002
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @brief Prototype for *.c in ./missing, and for missing timeval struct.
*/
#include "ruby/internal/config.h"
#ifdef STDC_HEADERS
# include <stddef.h>
#endif
#if defined(__cplusplus)
# include <cmath>
#else
# include <math.h> /* for INFINITY and NAN */
#endif
#ifdef RUBY_ALTERNATIVE_MALLOC_HEADER
# include RUBY_ALTERNATIVE_MALLOC_HEADER
#endif
#if defined(HAVE_TIME_H)
# include <time.h>
#endif
#if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif
#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif
#include "ruby/internal/dllexport.h"
#include "ruby/internal/attr/format.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
# define M_PI_2 (M_PI/2)
#endif
#if !defined(HAVE_STRUCT_TIMEVAL)
struct timeval {
time_t tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
#endif /* HAVE_STRUCT_TIMEVAL */
#if !defined(HAVE_STRUCT_TIMESPEC)
/* :BEWARE: @shyouhei warns that IT IS A WRONG IDEA to define our own version
* of struct timespec here. `clock_gettime` is a system call, and your kernel
* could expect something other than just `long` (results stack smashing if
* that happens). See also https://ewontfix.com/19/ */
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
#if !defined(HAVE_STRUCT_TIMEZONE)
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
#endif
RBIMPL_SYMBOL_EXPORT_BEGIN()
#ifndef HAVE_ACOSH
RUBY_EXTERN double acosh(double);
RUBY_EXTERN double asinh(double);
RUBY_EXTERN double atanh(double);
#endif
#ifndef HAVE_CRYPT
RUBY_EXTERN char *crypt(const char *, const char *);
#endif
#ifndef HAVE_EACCESS
RUBY_EXTERN int eaccess(const char*, int);
#endif
#ifndef HAVE_ROUND
RUBY_EXTERN double round(double); /* numeric.c */
#endif
#ifndef HAVE_FLOCK
RUBY_EXTERN int flock(int, int);
#endif
/*
#ifndef HAVE_FREXP
RUBY_EXTERN double frexp(double, int *);
#endif
*/
#ifndef HAVE_HYPOT
RUBY_EXTERN double hypot(double, double);
#endif
#ifndef HAVE_ERF
RUBY_EXTERN double erf(double);
RUBY_EXTERN double erfc(double);
#endif
#ifndef HAVE_TGAMMA
RUBY_EXTERN double tgamma(double);
#endif
#ifndef HAVE_LGAMMA_R
RUBY_EXTERN double lgamma_r(double, int *);
#endif
#ifndef HAVE_CBRT
RUBY_EXTERN double cbrt(double);
#endif
#if !defined(INFINITY) || !defined(NAN)
union bytesequence4_or_float {
unsigned char bytesequence[4];
float float_value;
};
#endif
#ifndef INFINITY
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_infinity;
# define INFINITY (rb_infinity.float_value)
# define USE_RB_INFINITY 1
#endif
#ifndef NAN
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_nan;
# define NAN (rb_nan.float_value)
# define USE_RB_NAN 1
#endif
#ifndef HUGE_VAL
# define HUGE_VAL ((double)INFINITY)
#endif
#ifndef HAVE_FINITE
# define HAVE_FINITE 1
# define finite(x) isfinite(x)
#endif
#ifndef HAVE_NAN
RUBY_EXTERN double nan(const char *);
#endif
#ifndef HAVE_NEXTAFTER
RUBY_EXTERN double nextafter(double x, double y);
#endif
/*
#ifndef HAVE_MEMCMP
RUBY_EXTERN int memcmp(const void *, const void *, size_t);
#endif
*/
#ifndef HAVE_MEMMOVE
RUBY_EXTERN void *memmove(void *, const void *, size_t);
#endif
/*
#ifndef HAVE_MODF
RUBY_EXTERN double modf(double, double *);
#endif
*/
#ifndef HAVE_STRCHR
RUBY_EXTERN char *strchr(const char *, int);
RUBY_EXTERN char *strrchr(const char *, int);
#endif
#ifndef HAVE_STRERROR
RUBY_EXTERN char *strerror(int);
#endif
#ifndef HAVE_STRSTR
RUBY_EXTERN char *strstr(const char *, const char *);
#endif
#ifndef HAVE_STRLCPY
RUBY_EXTERN size_t strlcpy(char *, const char*, size_t);
#endif
#ifndef HAVE_STRLCAT
RUBY_EXTERN size_t strlcat(char *, const char*, size_t);
#endif
#ifndef HAVE_FFS
RUBY_EXTERN int ffs(int);
#endif
#ifdef BROKEN_CLOSE
# include <sys/types.h>
# include <sys/socket.h>
RUBY_EXTERN int ruby_getpeername(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_getsockname(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_shutdown(int, int);
RUBY_EXTERN int ruby_close(int);
#endif
#ifndef HAVE_SETPROCTITLE
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
RUBY_EXTERN void setproctitle(const char *fmt, ...);
#endif
#ifdef HAVE_EXPLICIT_BZERO
# /* Take that. */
#elif defined(SecureZeroMemory)
# define explicit_bzero(b, len) SecureZeroMemory(b, len)
#else
RUBY_EXTERN void explicit_bzero(void *b, size_t len);
#endif
#ifndef HAVE_TZSET
RUBY_EXTERN void tzset(void);
#endif
#ifndef HAVE_POSIX_MADVISE
RUBY_EXTERN int posix_madvise(void *, size_t, int);
#endif
#ifndef HAVE_GETEUID
RUBY_EXTERN rb_uid_t geteuid(void);
#endif
#ifndef HAVE_GETUID
RUBY_EXTERN rb_uid_t getuid(void);
#endif
#ifndef HAVE_GETEGID
RUBY_EXTERN rb_gid_t getegid(void);
#endif
#ifndef HAVE_GETGID
RUBY_EXTERN rb_gid_t getgid(void);
#endif
#ifndef HAVE_GETLOGIN
RUBY_EXTERN char *getlogin(void);
#endif
#ifndef HAVE_GETPPID
RUBY_EXTERN rb_pid_t getppid(void);
#endif
#ifndef HAVE_UMASK
RUBY_EXTERN rb_mode_t umask(rb_mode_t);
#endif
#ifndef HAVE_CHMOD
RUBY_EXTERN int chmod(const char *, rb_mode_t);
#endif
#ifndef HAVE_CHOWN
RUBY_EXTERN int chown(const char *, rb_uid_t, rb_gid_t);
#endif
#ifndef HAVE_PCLOSE
RUBY_EXTERN int pclose(FILE *);
#endif
#ifndef HAVE_POPEN
RUBY_EXTERN FILE *popen(const char *, const char *);
#endif
#ifndef HAVE_PIPE
RUBY_EXTERN int pipe(int [2]);
#endif
#ifndef HAVE_DUP
RUBY_EXTERN int dup(int);
#endif
#ifndef HAVE_DUP2
RUBY_EXTERN int dup2(int, int);
#endif
#ifndef HAVE_KILL
RUBY_EXTERN int kill(rb_pid_t, int);
#endif
#ifndef HAVE_EXECL
RUBY_EXTERN int execl(const char *, const char *, ...);
#endif
#ifndef HAVE_EXECLE
RUBY_EXTERN int execle(const char *, const char *, ...);
#endif
#ifndef HAVE_EXECV
RUBY_EXTERN int execv(const char *, char *const []);
#endif
#ifndef HAVE_EXECVE
RUBY_EXTERN int execve(const char *, char *const [], char *const []);
#endif
#ifndef HAVE_SHUTDOWN
RUBY_EXTERN int shutdown(int, int);
#endif
#ifndef HAVE_SYSTEM
RUBY_EXTERN int system(const char *);
#endif
#ifndef WNOHANG
# define WNOHANG 0
#endif
#ifndef HAVE_WAITPID
# define HAVE_WAITPID 1
RUBY_EXTERN rb_pid_t waitpid(rb_pid_t, int *, int);
#endif
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_MISSING_H */
include/ruby/thread_native.h 0000644 00000015111 15040330607 0012133 0 ustar 00 #ifndef RUBY_THREAD_NATIVE_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_NATIVE_H 1
/**
* @file
* @author $Author: ko1 $
* @date Wed May 14 19:37:31 2014
* @copyright Copyright (C) 2014 Yukihiro Matsumoto
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*
* This file contains wrapper APIs for native thread primitives
* which Ruby interpreter uses.
*
* Now, we only support pthread and Windows threads.
*
* If you want to use Ruby's Mutex and so on to synchronize Ruby Threads,
* please use Mutex directly.
*/
#if defined(_WIN32)
#include <windows.h>
typedef HANDLE rb_nativethread_id_t;
typedef union rb_thread_lock_union {
HANDLE mutex;
CRITICAL_SECTION crit;
} rb_nativethread_lock_t;
typedef struct rb_thread_cond_struct rb_nativethread_cond_t;
#elif defined(HAVE_PTHREAD_H)
#include <pthread.h>
typedef pthread_t rb_nativethread_id_t;
typedef pthread_mutex_t rb_nativethread_lock_t;
typedef pthread_cond_t rb_nativethread_cond_t;
#elif defined(__wasi__) // no-thread platforms
typedef struct rb_nativethread_id_t *rb_nativethread_id_t;
typedef struct rb_nativethread_lock_t *rb_nativethread_lock_t;
typedef struct rb_nativethread_cond_t *rb_nativethread_cond_t;
#elif defined(__DOXYGEN__)
/** Opaque type that holds an ID of a native thread. */
struct rb_nativethread_id_t;
/** Opaque type that holds a lock. */
struct rb_nativethread_lock_t;
/** Opaque type that holds a condition variable. */
struct rb_nativethread_cond_t;
#else
#error "unsupported thread type"
#endif
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* Queries the ID of the native thread that is calling this function.
*
* @return The caller thread's native ID.
*/
rb_nativethread_id_t rb_nativethread_self(void);
/**
* Fills the passed lock with an initial value.
*
* @param[out] lock A mutex to initialise.
* @post `lock` is updated to its initial state.
*
* @internal
*
* There is no data structure that analogous to pthread_once_t in ruby. It is
* pretty much tricky (if not impossible) to properly initialise a mutex
* exactly once.
*/
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock);
/**
* Destroys the passed mutex.
*
* @param[out] lock A mutex to kill.
* @post `lock` is no longer eligible for other functions.
*
* @internal
*
* It is an undefined behaviour (see `pthread_mutex_destroy(3posix)`) to
* destroy a locked mutex. So it has to be unlocked. But an unlocked mutex
* can of course be locked by another thread. That's the ultimate reason why
* we do mutex. There is an inevitable race condition here. 2017 edition of
* IEEE 1003.1 issue 7 says in its rationale that "care must be taken". Care?
* How?
*
* @shyouhei thinks that POSIX is broken by design.
*/
void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);
/**
* Blocks until the current thread obtains a lock.
*
* @param[out] lock A mutex to lock.
* @post `lock` is owned by the current native thread.
*/
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);
/**
* Releases a lock.
*
* @param[out] lock A mutex to unlock.
* @pre `lock` is owned by the current native thread.
* @post `lock` is not owned by the current native thread.
*/
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);
/** @alias{rb_nativethread_lock_lock} */
void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
/**
* Identical to rb_native_mutex_lock(), except it doesn't block in case
* rb_native_mutex_lock() would.
*
* @param[out] lock A mutex to lock.
* @retval 0 `lock` is successfully owned by the current thread.
* @retval EBUSY `lock` is owned by someone else.
*/
int rb_native_mutex_trylock(rb_nativethread_lock_t *lock);
/** @alias{rb_nativethread_lock_unlock} */
void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
/** @alias{rb_nativethread_lock_initialize} */
void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
/** @alias{rb_nativethread_lock_destroy} */
void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
/**
* Signals a condition variable.
*
* @param[out] cond A condition variable to ping.
* @post More than one threads waiting for `cond` gets signalled.
* @note This function can spuriously wake multiple threads up.
* `pthread_cond_signal(3posix)` says it can even be "impossible
* to avoid the unblocking of more than one thread blocked on a
* condition variable". Just brace spurious wakeups.
*/
void rb_native_cond_signal(rb_nativethread_cond_t *cond);
/**
* Signals a condition variable.
*
* @param[out] cond A condition variable to ping.
* @post All threads waiting for `cond` gets signalled.
*/
void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
/**
* Waits for the passed condition variable to be signalled.
*
* @param[out] cond A condition variable to wait.
* @param[out] mutex A mutex.
* @pre `mutex` is owned by the current thread.
* @post `mutex` is owned by the current thread.
* @note This can wake up spuriously.
*/
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
/**
* Identical to rb_native_cond_wait(), except it additionally takes timeout in
* msec resolution. Timeouts can be detected by catching exceptions.
*
* @param[out] cond A condition variable to wait.
* @param[out] mutex A mutex.
* @param[in] msec Timeout.
* @exception rb_eSystemCallError `Errno::ETIMEDOUT` for timeout.
* @pre `mutex` is owned by the current thread.
* @post `mutex` is owned by the current thread.
* @note This can wake up spuriously.
*/
void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec);
/**
* Fills the passed condition variable with an initial value.
*
* @param[out] cond A condition variable to initialise.
* @post `cond` is updated to its initial state.
*/
void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
/**
* Destroys the passed condition variable.
*
* @param[out] cond A condition variable to kill.
* @post `cond` is no longer eligible for other functions.
*/
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
RBIMPL_SYMBOL_EXPORT_END()
#endif
include/ruby/version.h 0000644 00000011413 15040330607 0011004 0 ustar 00 #ifndef RUBY_VERSION_H /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_VERSION_H 1
/**
* @file
* @author $Author$
* @date Wed May 13 12:56:56 JST 2009
* @copyright Copyright (C) 1993-2009 Yukihiro Matsumoto
* @copyright Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
* @copyright Copyright (C) 2000 Information-technology Promotion Agency, Japan
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*
* This file contains only
* - never-changeable information, and
* - interfaces accessible from extension libraries.
*
* Never try to check RUBY_VERSION_CODE etc in extension libraries,
* check the features with mkmf.rb instead.
*/
/**
* @name The origin.
*
* These information never change. Just written here to remember.
*
* @{
*/
/** Author of this project. */
#define RUBY_AUTHOR "Yukihiro Matsumoto"
/** Ruby's birth year. */
#define RUBY_BIRTH_YEAR 1993
/** Ruby's birth month. */
#define RUBY_BIRTH_MONTH 2
/** Ruby's birth day. */
#define RUBY_BIRTH_DAY 24
/** @} */
/**
* @name The API version.
*
* API version is different from binary version. These numbers are for API
* stability. When you have distinct API versions x and y, you cannot expect
* codes targeted to x also works for y.
*
* However let us repeat here that it's a BAD idea to check
* #RUBY_API_VERSION_CODE form extension libraries. Different API versions are
* just different. There is no such thing like upper compatibility.
*
* @{
*/
/**
* Major version. This digit changes sometimes for various reasons, but that
* doesn't mean a total rewrite. Practically when it comes to API versioning,
* major and minor version changes are equally catastrophic.
*/
#define RUBY_API_VERSION_MAJOR 3
/**
* Minor version. As of writing this version changes annually. Greater
* version doesn't mean "better"; they just mean years passed.
*/
#define RUBY_API_VERSION_MINOR 2
/**
* Teeny version. This digit is kind of reserved these days. Kept 0 for the
* entire 2.x era. Waiting for future uses.
*/
#define RUBY_API_VERSION_TEENY 0
/**
* This macro is API versions encoded into a C integer.
*
* @note Use mkmf.
* @note Don't rely on it.
*/
#define RUBY_API_VERSION_CODE (RUBY_API_VERSION_MAJOR*10000+RUBY_API_VERSION_MINOR*100+RUBY_API_VERSION_TEENY)
/** @} */
#ifdef RUBY_EXTERN
/* Internal note: this file could be included from verconf.mk _before_
* generating config.h, on Windows. The #ifdef above is to trick such
* situation. */
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
* @name Interfaces from extension libraries.
*
* Before using these infos, think thrice whether they are really
* necessary or not, and if the answer was yes, think twice a week
* later again.
*
* @{
*/
/** API versions, in { major, minor, teeny } order. */
RUBY_EXTERN const int ruby_api_version[3];
/**
* Stringised version.
*
* @note This is the runtime version, not the API version. For instance it
* was `"2.5.9"` when ::ruby_api_version was `{ 2, 5, 0 }`.
*/
RUBY_EXTERN const char ruby_version[];
/** Date of release, in a C string. */
RUBY_EXTERN const char ruby_release_date[];
/**
* Target platform identifier, in a C string.
*
* @note Seasoned UNIX programmers should beware that this "platform
* identifier" is our invention; not always identical to so-called
* target triplets that GNU systems use. For instance on @shyouhei's
* machine, ::ruby_platform is `"x64_64-linux"` while its target triplet
* is `x86_64-pc-linux-gnu`.
* @note Note also that we support Windows.
*/
RUBY_EXTERN const char ruby_platform[];
/**
* This is a monotonic increasing integer that describes specific "patch"
* level. You can know the exact changeset your binary is running by this info
* (and ::ruby_version), unless this is -1. -1 means there is no release yet
* for the version; ruby is actively developed. 0 means the initial GA version.
*/
RUBY_EXTERN const int ruby_patchlevel;
/**
* This is what `ruby -v` prints to the standard error. Something like:
* `"ruby 2.5.9p229 (2021-04-05 revision 67829) [x86_64-linux]"`. This doesn't
* include runtime options like a JIT being enabled.
*/
RUBY_EXTERN const char ruby_description[];
/** Copyright notice. */
RUBY_EXTERN const char ruby_copyright[];
/**
* This is just `"ruby"` for us. But different implementations can have
* different strings here.
*/
RUBY_EXTERN const char ruby_engine[];
/** @} */
RBIMPL_SYMBOL_EXPORT_END()
#endif
#endif
bin/bundler 0000755 00000001075 15040330607 0006676 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'bundler' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ENV['BUNDLER_VERSION'] = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundler', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundler", version)
end
bin/gem 0000755 00000000345 15040330607 0006012 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require "rubygems/gem_runner"
Gem::GemRunner.new.run ARGV.clone
bin/syntax_suggest 0000755 00000001126 15040330607 0010327 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'syntax_suggest' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
Gem.use_gemdeps
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('syntax_suggest', 'syntax_suggest', version)
else
gem "syntax_suggest", version
load Gem.bin_path("syntax_suggest", "syntax_suggest", version)
end
bin/rdoc 0000755 00000001032 15040330607 0006163 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'rdoc' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
Gem.use_gemdeps
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('rdoc', 'rdoc', version)
else
gem "rdoc", version
load Gem.bin_path("rdoc", "rdoc", version)
end
bin/rackup 0000755 00000001046 15040330607 0006526 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'rackup' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
Gem.use_gemdeps
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('rackup', 'rackup', version)
else
gem "rackup", version
load Gem.bin_path("rackup", "rackup", version)
end
bin/rake 0000755 00000001032 15040330607 0006156 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
Gem.use_gemdeps
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('rake', 'rake', version)
else
gem "rake", version
load Gem.bin_path("rake", "rake", version)
end
bin/erb 0000755 00000001024 15040330607 0006005 0 ustar 00 #!/opt/alt/ruby32/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'erb' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
Gem.use_gemdeps
version = ">= 0.a"
str = ARGV.first
if str
str = str.b[/\A_(.*)_\z/, 1]
if str and Gem::Version.correct?(str)
version = str
ARGV.shift
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('erb', 'erb', version)
else
gem "erb", version
load Gem.bin_path("erb", "erb", version)
end
bin/ruby 0000755 00000027510 15040330607 0006226 0 ustar 00 ELF >