Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce2b59aeb9 | |||
| 40ed515f3d | |||
| 7e4059e445 | |||
| f15663a1e7 | |||
| f359e276ca | |||
| 89ad1f0ba0 | |||
| 3cce3fb807 |
@@ -3,3 +3,4 @@ Debug*
|
||||
Release*
|
||||
x64/
|
||||
.DS_Store
|
||||
xcuserdata
|
||||
+2
-1
@@ -5,4 +5,5 @@ EXPORTS
|
||||
Init_sqlite3_20
|
||||
Init_sqlite3_22
|
||||
Init_sqlite3_25
|
||||
Init_sqlite3_27
|
||||
Init_sqlite3_27
|
||||
Init_sqlite3_32
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,458 @@
|
||||
#ifndef INCLUDE_RUBY_CONFIG_H
|
||||
#define INCLUDE_RUBY_CONFIG_H 1
|
||||
/* confdefs.h */
|
||||
#define HAVE_STDIO_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_INTTYPES_H 1
|
||||
#define HAVE_STDINT_H 1
|
||||
#define HAVE_STRINGS_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_WCHAR_H 1
|
||||
#define STDC_HEADERS 1
|
||||
#define _ALL_SOURCE 1
|
||||
#define _DARWIN_C_SOURCE 1
|
||||
#define _GNU_SOURCE 1
|
||||
#define _HPUX_ALT_XOPEN_SOCKET_API 1
|
||||
#define _NETBSD_SOURCE 1
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
|
||||
#define __STDC_WANT_IEC_60559_BFP_EXT__ 1
|
||||
#define __STDC_WANT_IEC_60559_DFP_EXT__ 1
|
||||
#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
|
||||
#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
|
||||
#define __STDC_WANT_LIB_EXT2__ 1
|
||||
#define __STDC_WANT_MATH_SPEC_FUNCS__ 1
|
||||
#define _TANDEM_SOURCE 1
|
||||
#define __EXTENSIONS__ 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 BROKEN_CRYPT 1
|
||||
#define HAVE_CRT_EXTERNS_H 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_COPYFILE_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_MALLOC_H 1
|
||||
#define HAVE_PWD_H 1
|
||||
#define HAVE_SANITIZER_ASAN_INTERFACE_H 1
|
||||
#define HAVE_SANITIZER_MSAN_INTERFACE_H 1
|
||||
#define HAVE_STDALIGN_H 1
|
||||
#define HAVE_STDIO_H 1
|
||||
#define HAVE_SYS_ATTR_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_RANDOM_H 1
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_SYS_TIMES_H 1
|
||||
#define HAVE_SYS_UIO_H 1
|
||||
#define HAVE_TIME_H 1
|
||||
#define HAVE_UCONTEXT_H 1
|
||||
#define HAVE_UTIME_H 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) INT2NUM(v)
|
||||
#define NUM2DEVT(v) NUM2INT(v)
|
||||
#define PRI_DEVT_PREFIX PRI_INT_PREFIX
|
||||
#define HAVE_MODE_T 1
|
||||
#define rb_mode_t mode_t
|
||||
#define SIGNEDNESS_OF_MODE_T +1
|
||||
#define MODET2NUM(v) USHORT2NUM(v)
|
||||
#define NUM2MODET(v) NUM2USHORT(v)
|
||||
#define PRI_MODET_PREFIX PRI_SHORT_PREFIX
|
||||
#define HAVE_RLIM_T 1
|
||||
#define rb_rlim_t rlim_t
|
||||
#define SIGNEDNESS_OF_RLIM_T +1
|
||||
#define RLIM2NUM(v) ULL2NUM(v)
|
||||
#define NUM2RLIM(v) NUM2ULL(v)
|
||||
#define PRI_RLIM_PREFIX PRI_LL_PREFIX
|
||||
#define HAVE_OFF_T 1
|
||||
#define rb_off_t off_t
|
||||
#define SIGNEDNESS_OF_OFF_T -1
|
||||
#define OFFT2NUM(v) LL2NUM(v)
|
||||
#define NUM2OFFT(v) NUM2LL(v)
|
||||
#define PRI_OFFT_PREFIX PRI_LL_PREFIX
|
||||
#define HAVE_CLOCKID_T 1
|
||||
#define rb_clockid_t clockid_t
|
||||
#define SIGNEDNESS_OF_CLOCKID_T +1
|
||||
#define CLOCKID2NUM(v) UINT2NUM(v)
|
||||
#define NUM2CLOCKID(v) NUM2UINT(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_CDECL(x) __attribute__ ((__cdecl__)) x
|
||||
#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 4
|
||||
#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_ATIMESPEC 1
|
||||
#define HAVE_STRUCT_STAT_ST_MTIMESPEC 1
|
||||
#define HAVE_STRUCT_STAT_ST_CTIMESPEC 1
|
||||
#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC 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 PRI_PTR_PREFIX "l"
|
||||
#define HAVE_SSIZE_T 1
|
||||
#define SIZEOF_SSIZE_T 8
|
||||
#define PRI_64_PREFIX "ll"
|
||||
#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_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_STRLCAT 1
|
||||
#define HAVE_STRLCPY 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 vfork fork
|
||||
#define HAVE_WORKING_FORK 1
|
||||
#define HAVE__LONGJMP 1
|
||||
#define HAVE_ARC4RANDOM_BUF 1
|
||||
#define HAVE_ATAN2L 1
|
||||
#define HAVE_ATAN2F 1
|
||||
#define HAVE_CHMOD 1
|
||||
#define HAVE_CHOWN 1
|
||||
#define HAVE_CHROOT 1
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
#define HAVE_COSH 1
|
||||
#define HAVE_DIRFD 1
|
||||
#define HAVE_DLOPEN 1
|
||||
#define HAVE_DLADDR 1
|
||||
#define HAVE_ENDGRENT 1
|
||||
#define HAVE_EXECL 1
|
||||
#define HAVE_EXECLE 1
|
||||
#define HAVE_EXECV 1
|
||||
#define HAVE_EXECVE 1
|
||||
#define HAVE_FCOPYFILE 1
|
||||
#define HAVE_FCHMOD 1
|
||||
#define HAVE_FCHOWN 1
|
||||
#define HAVE_FCNTL 1
|
||||
#define HAVE_FDOPENDIR 1
|
||||
#define HAVE_FGETATTRLIST 1
|
||||
#define HAVE_FMOD 1
|
||||
#define HAVE_FSTATAT 1
|
||||
#define HAVE_FSYNC 1
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define HAVE_GETATTRLIST 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_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_ISSETUGID 1
|
||||
#define HAVE_KILL 1
|
||||
#define HAVE_KILLPG 1
|
||||
#define HAVE_LCHMOD 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_SIZE 1
|
||||
#define HAVE_MBLEN 1
|
||||
#define HAVE_MEMSET_S 1
|
||||
#define HAVE_WRITEV 1
|
||||
#define HAVE_MEMMEM 1
|
||||
#define HAVE_MKFIFO 1
|
||||
#define HAVE_MKNOD 1
|
||||
#define HAVE_MKTIME 1
|
||||
#define HAVE_MMAP 1
|
||||
#define HAVE_OPENAT 1
|
||||
#define HAVE_PCLOSE 1
|
||||
#define HAVE_PIPE 1
|
||||
#define HAVE_POLL 1
|
||||
#define HAVE_POPEN 1
|
||||
#define HAVE_POSIX_MADVISE 1
|
||||
#define HAVE_POSIX_MEMALIGN 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_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_SETREUID 1
|
||||
#define HAVE_SETRGID 1
|
||||
#define HAVE_SETRLIMIT 1
|
||||
#define HAVE_SETRUID 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_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_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___COSPI 1
|
||||
#define HAVE___SINPI 1
|
||||
#if !defined __STDC_WANT_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif /* !defined __STDC_WANT_LIB_EXT1__ */
|
||||
#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_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_BSD_QSORT_R 1
|
||||
#define ATAN2_INF_C99 1
|
||||
#define HAVE_CLOCK_GETRES 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 HAVE__SC_CLK_TCK 1
|
||||
#define STACK_GROW_DIRECTION -1
|
||||
#define COROUTINE_H "coroutine/arm64/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_GET_STACKADDR_NP 1
|
||||
#define HAVE_PTHREAD_GET_STACKSIZE_NP 1
|
||||
#define HAVE_PTHREAD_SETNAME_NP 1
|
||||
#define HAVE_PTHREAD_SIGMASK 1
|
||||
#define SET_CURRENT_THREAD_NAME(name) pthread_setname_np(name)
|
||||
#define DEFINE_MCONTEXT_PTR(mc, uc) mcontext_t mc = (uc)->uc_mcontext
|
||||
#define HAVE_SYS_USER_H 1
|
||||
#define HAVE_CONST_PAGE_SIZE 0
|
||||
#define IOCTL_REQ_TYPE unsigned long
|
||||
#define NUM2IOCTLREQ(num) NUM2ULONG(num)
|
||||
#define HAVE_MACH_O_LOADER_H 1
|
||||
#define EXTSTATIC 1
|
||||
#define HAVE_LIBPROC_H 1
|
||||
#define HAVE_EXECINFO_H 1
|
||||
#define HAVE_LIBUNWIND_H 1
|
||||
#define HAVE_MACH_TASK_H 1
|
||||
#define HAVE_MACH_MACH_INIT_H 1
|
||||
#define HAVE_MACH_MACH_PORT_H 1
|
||||
#define HAVE_MACH_TASK_EXCEPTION_PORTS 1
|
||||
#define HAVE_BACKTRACE 1
|
||||
#define BROKEN_BACKTRACE 1
|
||||
#define DLEXT_MAXLEN 7
|
||||
#define DLEXT ".bundle"
|
||||
#define LIBDIR_BASENAME "lib"
|
||||
#define HAVE__SETJMP 1
|
||||
#define HAVE_SIGSETJMP 1
|
||||
#define RUBY_SETJMP(env) sigsetjmp((env),0)
|
||||
#define RUBY_LONGJMP(env,val) siglongjmp((env),val)
|
||||
#define RUBY_JMP_BUF sigjmp_buf
|
||||
#define USE_MJIT 1
|
||||
#define USE_YJIT 0
|
||||
#define LOAD_RELATIVE 1
|
||||
#define RUBY_PLATFORM "arm64-darwin22"
|
||||
#endif /* INCLUDE_RUBY_CONFIG_H */
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#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 */
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
#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 */
|
||||
+890
@@ -0,0 +1,890 @@
|
||||
#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 */
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,56 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,165 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,36 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,37 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,131 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,99 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,73 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,36 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,30 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,69 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,700 @@
|
||||
#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
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef RUBY_CONFIG_SHIM_H
|
||||
#define RUBY_CONFIG_SHIM_H 1
|
||||
|
||||
#ifdef __aarch64__
|
||||
#include "../arm64-darwin/ruby/config.h"
|
||||
#else
|
||||
#include "../x86_64-darwin/ruby/config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
#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 */
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/************************************************
|
||||
|
||||
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));
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,374 @@
|
||||
#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 */
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,58 @@
|
||||
#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
|
||||
@@ -0,0 +1,376 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,39 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,81 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,72 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,60 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,41 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,264 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,74 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,356 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,135 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,41 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,62 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,41 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,113 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,66 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,75 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,41 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,87 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,46 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,37 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,46 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,84 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,75 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,42 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,33 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,40 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,38 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,38 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,69 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,45 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,91 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,35 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,34 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,48 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,43 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,44 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,37 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,32 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,50 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,45 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,40 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,37 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,45 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,40 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,56 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,54 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,61 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,155 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,38 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,35 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,585 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,158 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,80 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,93 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,386 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,51 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,144 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,146 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,176 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,168 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,578 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,121 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,604 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,545 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,112 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,89 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,202 @@
|
||||
#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 */
|
||||
@@ -0,0 +1,258 @@
|
||||
#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 */
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user