rubycc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +56 -0
  3. data/LICENSE.txt +21 -0
  4. data/NOTICE +52 -0
  5. data/README.md +208 -0
  6. data/data/README.md +117 -0
  7. data/data/r10_corpus_scan.json +4082 -0
  8. data/data/r10_manual_classification.json +5342 -0
  9. data/data/r10_verification_m4a.json +1531 -0
  10. data/data/r10_verification_m4b.json +1818 -0
  11. data/data/r10_verification_m4c.json +1489 -0
  12. data/data/r10_verification_m4d.json +318 -0
  13. data/data/r10_verification_rbs.json +192 -0
  14. data/data/verified_gems.json +397 -0
  15. data/exe/rmake +16 -0
  16. data/exe/rubycc +9 -0
  17. data/exe/rubycc-ar +114 -0
  18. data/exe/rubycc-doctor +14 -0
  19. data/exe/rubycc-pkgconf +8 -0
  20. data/include/float.h +87 -0
  21. data/include/iso646.h +18 -0
  22. data/include/libc/alloca.h +18 -0
  23. data/include/libc/arpa/inet.h +61 -0
  24. data/include/libc/assert.h +43 -0
  25. data/include/libc/dirent.h +72 -0
  26. data/include/libc/dlfcn.h +58 -0
  27. data/include/libc/features.h +205 -0
  28. data/include/libc/glibc/aarch64/ctype.h +108 -0
  29. data/include/libc/glibc/aarch64/endian.h +54 -0
  30. data/include/libc/glibc/aarch64/errno.h +154 -0
  31. data/include/libc/glibc/aarch64/fcntl.h +144 -0
  32. data/include/libc/glibc/aarch64/inttypes.h +182 -0
  33. data/include/libc/glibc/aarch64/limits.h +63 -0
  34. data/include/libc/glibc/aarch64/pthread.h +131 -0
  35. data/include/libc/glibc/aarch64/setjmp.h +84 -0
  36. data/include/libc/glibc/aarch64/stdint.h +174 -0
  37. data/include/libc/glibc/aarch64/sys/epoll.h +88 -0
  38. data/include/libc/glibc/aarch64/sys/fcntl.h +19 -0
  39. data/include/libc/glibc/aarch64/sys/select.h +75 -0
  40. data/include/libc/glibc/aarch64/sys/stat.h +136 -0
  41. data/include/libc/glibc/aarch64/sys/syscall.h +167 -0
  42. data/include/libc/glibc/aarch64/sys/time.h +74 -0
  43. data/include/libc/glibc/aarch64/sys/types.h +127 -0
  44. data/include/libc/glibc/aarch64/time.h +113 -0
  45. data/include/libc/glibc/x86_64/ctype.h +108 -0
  46. data/include/libc/glibc/x86_64/endian.h +54 -0
  47. data/include/libc/glibc/x86_64/errno.h +154 -0
  48. data/include/libc/glibc/x86_64/fcntl.h +134 -0
  49. data/include/libc/glibc/x86_64/inttypes.h +182 -0
  50. data/include/libc/glibc/x86_64/limits.h +61 -0
  51. data/include/libc/glibc/x86_64/pthread.h +111 -0
  52. data/include/libc/glibc/x86_64/setjmp.h +82 -0
  53. data/include/libc/glibc/x86_64/stdint.h +163 -0
  54. data/include/libc/glibc/x86_64/sys/epoll.h +91 -0
  55. data/include/libc/glibc/x86_64/sys/fcntl.h +19 -0
  56. data/include/libc/glibc/x86_64/sys/select.h +75 -0
  57. data/include/libc/glibc/x86_64/sys/stat.h +130 -0
  58. data/include/libc/glibc/x86_64/sys/syscall.h +188 -0
  59. data/include/libc/glibc/x86_64/sys/time.h +74 -0
  60. data/include/libc/glibc/x86_64/sys/types.h +123 -0
  61. data/include/libc/glibc/x86_64/time.h +113 -0
  62. data/include/libc/grp.h +50 -0
  63. data/include/libc/langinfo.h +126 -0
  64. data/include/libc/link.h +18 -0
  65. data/include/libc/locale.h +83 -0
  66. data/include/libc/math.h +191 -0
  67. data/include/libc/netinet/in.h +126 -0
  68. data/include/libc/netinet/tcp.h +44 -0
  69. data/include/libc/poll.h +46 -0
  70. data/include/libc/pwd.h +58 -0
  71. data/include/libc/regex.h +53 -0
  72. data/include/libc/sched.h +35 -0
  73. data/include/libc/signal.h +204 -0
  74. data/include/libc/stdio.h +157 -0
  75. data/include/libc/stdlib.h +92 -0
  76. data/include/libc/string.h +74 -0
  77. data/include/libc/strings.h +25 -0
  78. data/include/libc/sys/cdefs.h +126 -0
  79. data/include/libc/sys/inotify.h +111 -0
  80. data/include/libc/sys/ioctl.h +36 -0
  81. data/include/libc/sys/mman.h +65 -0
  82. data/include/libc/sys/param.h +41 -0
  83. data/include/libc/sys/resource.h +109 -0
  84. data/include/libc/sys/socket.h +167 -0
  85. data/include/libc/sys/statfs.h +82 -0
  86. data/include/libc/sys/timerfd.h +55 -0
  87. data/include/libc/sys/uio.h +40 -0
  88. data/include/libc/sys/un.h +25 -0
  89. data/include/libc/sys/utsname.h +35 -0
  90. data/include/libc/sys/wait.h +135 -0
  91. data/include/libc/termios.h +179 -0
  92. data/include/libc/unistd.h +194 -0
  93. data/include/stdalign.h +16 -0
  94. data/include/stdarg.h +31 -0
  95. data/include/stdatomic.h +158 -0
  96. data/include/stdbool.h +15 -0
  97. data/include/stdckdint.h +28 -0
  98. data/include/stddef.h +60 -0
  99. data/include/stdnoreturn.h +18 -0
  100. data/include/x86intrin.h +16 -0
  101. data/lib/rubycc/backend/aarch64.rb +1724 -0
  102. data/lib/rubycc/backend/x86_64.rb +1369 -0
  103. data/lib/rubycc/compile_error.rb +36 -0
  104. data/lib/rubycc/compiler.rb +305 -0
  105. data/lib/rubycc/doctor/builder.rb +151 -0
  106. data/lib/rubycc/doctor/cli.rb +190 -0
  107. data/lib/rubycc/doctor/fetcher.rb +84 -0
  108. data/lib/rubycc/doctor/gemfile.rb +115 -0
  109. data/lib/rubycc/doctor/verified_gems.rb +114 -0
  110. data/lib/rubycc/doctor.rb +16 -0
  111. data/lib/rubycc/driver.rb +463 -0
  112. data/lib/rubycc/front/ast.rb +528 -0
  113. data/lib/rubycc/front/constant_evaluator.rb +631 -0
  114. data/lib/rubycc/front/initializer_resolver.rb +592 -0
  115. data/lib/rubycc/front/lexeme_reader.rb +460 -0
  116. data/lib/rubycc/front/lexer.rb +232 -0
  117. data/lib/rubycc/front/parser.rb +4122 -0
  118. data/lib/rubycc/front/token.rb +49 -0
  119. data/lib/rubycc/ir/call_convention.rb +486 -0
  120. data/lib/rubycc/ir/generator.rb +6036 -0
  121. data/lib/rubycc/ir/ir.rb +417 -0
  122. data/lib/rubycc/link/compat_runtime.rb +89 -0
  123. data/lib/rubycc/link/errors.rb +13 -0
  124. data/lib/rubycc/link/executable_linker.rb +405 -0
  125. data/lib/rubycc/link/library_resolver.rb +437 -0
  126. data/lib/rubycc/link/partial_linker.rb +546 -0
  127. data/lib/rubycc/link/shared_linker.rb +1732 -0
  128. data/lib/rubycc/mkmf_shim.rb +83 -0
  129. data/lib/rubycc/objfile/ar_archive.rb +437 -0
  130. data/lib/rubycc/objfile/elf_reader.rb +646 -0
  131. data/lib/rubycc/objfile/elf_writer.rb +891 -0
  132. data/lib/rubycc/objfile/relocatable_writer.rb +376 -0
  133. data/lib/rubycc/pkgconf/cli.rb +139 -0
  134. data/lib/rubycc/pkgconf/errors.rb +39 -0
  135. data/lib/rubycc/pkgconf/model.rb +28 -0
  136. data/lib/rubycc/pkgconf/parser.rb +109 -0
  137. data/lib/rubycc/pkgconf/pkgconf.rb +15 -0
  138. data/lib/rubycc/pkgconf/resolver.rb +70 -0
  139. data/lib/rubycc/pkgconf/search_path.rb +38 -0
  140. data/lib/rubycc/pkgconf/system_path_filter.rb +131 -0
  141. data/lib/rubycc/preprocess/constant_expression.rb +219 -0
  142. data/lib/rubycc/preprocess/glibc_version.rb +124 -0
  143. data/lib/rubycc/preprocess/pp_token.rb +62 -0
  144. data/lib/rubycc/preprocess/preprocessor.rb +2020 -0
  145. data/lib/rubycc/preprocess/scanner.rb +290 -0
  146. data/lib/rubycc/preprocess/token_converter.rb +157 -0
  147. data/lib/rubycc/rmake/cli.rb +143 -0
  148. data/lib/rubycc/rmake/errors.rb +71 -0
  149. data/lib/rubycc/rmake/executor.rb +818 -0
  150. data/lib/rubycc/rmake/expander.rb +251 -0
  151. data/lib/rubycc/rmake/makefile.rb +352 -0
  152. data/lib/rubycc/rmake/model.rb +137 -0
  153. data/lib/rubycc/rmake/parser.rb +226 -0
  154. data/lib/rubycc/rmake/rmake.rb +15 -0
  155. data/lib/rubycc/type.rb +1236 -0
  156. data/lib/rubycc/version.rb +5 -0
  157. data/lib/rubycc.rb +36 -0
  158. data/lib/rubygems_plugin.rb +102 -0
  159. metadata +219 -0
@@ -0,0 +1,111 @@
1
+ /* rubycc bundled <pthread.h>: the POSIX threads types, the mutex/attribute
2
+ enums and the core pthreads calls. Provenance: clean room against the glibc
3
+ pthreads ABI (bits/pthreadtypes.h, bits/pthreadtypes-arch.h and pthread.h),
4
+ not derived from musl or glibc source -- and a measured glibc ABI, not a
5
+ kernel UAPI, since the pthreads objects are glibc internal state rather than a
6
+ system-call interface. The opaque objects (pthread_mutex_t, pthread_cond_t,
7
+ pthread_attr_t and kin) are glibc implementation detail, so rubycc reproduces
8
+ only their measured size and alignment as an opaque byte blob -- a union of a
9
+ char __size[N] arm and the aligning scalar -- and does not copy glibc's
10
+ internal field layout (only what the ABI needs, exact; everything else opaque,
11
+ the same principle sys/stat.h follows for its reserved slots). Only that
12
+ size and alignment is an ABI fact reproduced by measurement, not copied text
13
+ (see docs/HEADER-LICENSING.md). The pthread_* calls are POSIX declarations
14
+ whose bodies resolve from the host libc at link time (glibc folds them into
15
+ libc), the same way errno.h's __errno_location does.
16
+ Placed in the glibc/x86-64 layer because the opaque sizes are arch dependent:
17
+ pthread_mutex_t, pthread_attr_t, pthread_mutexattr_t and pthread_condattr_t
18
+ are wider on aarch64, so a companion glibc/aarch64/pthread.h differs from this
19
+ file only in those four __size[N] counts (and this provenance line). */
20
+
21
+ #ifndef _RUBYCC_PTHREAD_H
22
+ #define _RUBYCC_PTHREAD_H
23
+
24
+ /* The thread handle and the small scalar handles (identical on both arches). */
25
+ typedef unsigned long pthread_t;
26
+ typedef int pthread_once_t;
27
+ typedef unsigned int pthread_key_t;
28
+ typedef int pthread_spinlock_t;
29
+
30
+ /* The opaque pthreads objects. Each carries real internal fields in glibc;
31
+ rubycc reproduces only the measured size and alignment as an opaque blob (the
32
+ char __size[N] arm alongside the aligning scalar), so a variable of the type
33
+ occupies the right space and alignment without copying glibc's field layout.
34
+ pthread_attr_t, pthread_mutex_t, pthread_mutexattr_t and pthread_condattr_t
35
+ have a wider __size[N] on aarch64 (the four counts that differ between the two
36
+ arch layers); the others are identical on both arches. */
37
+ typedef union { char __size[56]; long __align; } pthread_attr_t;
38
+ typedef union { char __size[40]; long __align; } pthread_mutex_t;
39
+ typedef union { char __size[4]; int __align; } pthread_mutexattr_t;
40
+ typedef union { char __size[48]; long __align; } pthread_cond_t;
41
+ typedef union { char __size[4]; int __align; } pthread_condattr_t;
42
+ typedef union { char __size[56]; long __align; } pthread_rwlock_t;
43
+ /* pthread_rwlockattr_t is the one object the two C libraries lay out
44
+ differently here: 8 bytes on both, but 4-byte aligned on musl against
45
+ glibc's 8 (both sizeof/_Alignof pairs measured with the ABI harness, glibc's
46
+ on this host and musl's on the CI musl run, docs/STEPS.md Step 193), so the
47
+ aligning scalar of the opaque union is the narrower one there. Every other
48
+ pthreads object above measured identical on the two libraries. */
49
+ #if defined(__RUBYCC_LIBC_MUSL__)
50
+ typedef union { char __size[8]; int __align; } pthread_rwlockattr_t;
51
+ #else
52
+ typedef union { char __size[8]; long __align; } pthread_rwlockattr_t;
53
+ #endif
54
+
55
+ /* Mutex kinds (pthread_mutexattr_settype / __kind). */
56
+ #define PTHREAD_MUTEX_NORMAL 0
57
+ #define PTHREAD_MUTEX_RECURSIVE 1
58
+ #define PTHREAD_MUTEX_ERRORCHECK 2
59
+ #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
60
+
61
+ /* Detach state (pthread_attr_setdetachstate). */
62
+ #define PTHREAD_CREATE_JOINABLE 0
63
+ #define PTHREAD_CREATE_DETACHED 1
64
+
65
+ /* Process-shared attribute values. */
66
+ #define PTHREAD_PROCESS_PRIVATE 0
67
+ #define PTHREAD_PROCESS_SHARED 1
68
+
69
+ /* Static initializers: zero the first arm of the opaque union. */
70
+ #define PTHREAD_MUTEX_INITIALIZER { { 0 } }
71
+ #define PTHREAD_COND_INITIALIZER { { 0 } }
72
+ #define PTHREAD_RWLOCK_INITIALIZER { { 0 } }
73
+ #define PTHREAD_ONCE_INIT 0
74
+
75
+ int pthread_create(pthread_t *__thread, const pthread_attr_t *__attr, void *(*__start)(void *), void *__arg);
76
+ int pthread_join(pthread_t __thread, void **__retval);
77
+ int pthread_detach(pthread_t __thread);
78
+ pthread_t pthread_self(void);
79
+ int pthread_equal(pthread_t __t1, pthread_t __t2);
80
+ int pthread_kill(pthread_t __thread, int __sig);
81
+ void pthread_exit(void *__retval);
82
+ int pthread_mutex_init(pthread_mutex_t *__mutex, const pthread_mutexattr_t *__attr);
83
+ int pthread_mutex_destroy(pthread_mutex_t *__mutex);
84
+ int pthread_mutex_lock(pthread_mutex_t *__mutex);
85
+ int pthread_mutex_trylock(pthread_mutex_t *__mutex);
86
+ int pthread_mutex_unlock(pthread_mutex_t *__mutex);
87
+ int pthread_cond_init(pthread_cond_t *__cond, const pthread_condattr_t *__attr);
88
+ int pthread_cond_destroy(pthread_cond_t *__cond);
89
+ int pthread_cond_wait(pthread_cond_t *__cond, pthread_mutex_t *__mutex);
90
+ int pthread_cond_signal(pthread_cond_t *__cond);
91
+ int pthread_cond_broadcast(pthread_cond_t *__cond);
92
+ int pthread_once(pthread_once_t *__once, void (*__init)(void));
93
+ int pthread_key_create(pthread_key_t *__key, void (*__destr)(void *));
94
+ int pthread_key_delete(pthread_key_t __key);
95
+ void *pthread_getspecific(pthread_key_t __key);
96
+ int pthread_setspecific(pthread_key_t __key, const void *__value);
97
+ int pthread_attr_init(pthread_attr_t *__attr);
98
+ int pthread_attr_destroy(pthread_attr_t *__attr);
99
+ int pthread_mutexattr_init(pthread_mutexattr_t *__attr);
100
+ int pthread_mutexattr_destroy(pthread_mutexattr_t *__attr);
101
+ int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __type);
102
+
103
+ /* Process-fork hook registration (a process-wide call, unlike the
104
+ thread-manipulation calls above). Declaring this turns stackprof's
105
+ build failure from a compile-time "implicit declaration" error into a
106
+ link-time one: glibc supplies pthread_atfork only from libc_nonshared.a,
107
+ whose member references __dso_handle, which rubycc's linker cannot yet
108
+ resolve (Step 146 gap 6, a separate, unfixed problem). */
109
+ int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void));
110
+
111
+ #endif /* _RUBYCC_PTHREAD_H */
@@ -0,0 +1,82 @@
1
+ /* rubycc bundled <setjmp.h>: the ISO C non-local jump facility (C11 7.13) plus
2
+ the POSIX sigsetjmp/siglongjmp pair. Provenance: clean room against the
3
+ glibc setjmp ABI (bits/setjmp.h, struct __jmp_buf_tag in bits/setjmpP.h),
4
+ not derived from musl or glibc source -- and a measured glibc ABI, not a
5
+ kernel UAPI, since jmp_buf is glibc internal state (a saved register set)
6
+ rather than a system-call interface. jmp_buf/sigjmp_buf are glibc
7
+ implementation detail (the callee-saved registers, stack pointer, program
8
+ counter, and -- for sigjmp_buf -- the saved signal mask), so rubycc
9
+ reproduces only their measured size and alignment as an opaque byte blob --
10
+ a union of a char __size[N] arm and the aligning scalar -- and does not copy
11
+ glibc's internal field layout (__jmpbuf / __mask_was_saved / __saved_mask),
12
+ the same principle pthread.h follows for its opaque objects. Only that size
13
+ and alignment is an ABI fact reproduced by measurement, not copied text (see
14
+ docs/HEADER-LICENSING.md). setjmp/longjmp/_setjmp/_longjmp/siglongjmp are
15
+ POSIX/ISO C declarations whose bodies resolve from the host libc at link
16
+ time (glibc folds them into libc), the same way errno.h's __errno_location
17
+ does. sigsetjmp is the one exception: glibc exports no plain `sigsetjmp'
18
+ symbol, only `__sigsetjmp' (measured: a plain `int sigsetjmp(...)'
19
+ declaration fails to link against glibc), so this header follows glibc's own
20
+ public macro contract and expands `sigsetjmp' onto `__sigsetjmp' -- a
21
+ documented interoperability fact, not copied glibc source.
22
+ Placed in the glibc/x86-64 layer because the opaque size is arch dependent:
23
+ jmp_buf holds one register set per architecture, so it is a different width
24
+ on aarch64 -- a companion glibc/aarch64/setjmp.h differs from this file only
25
+ in the __size[N] count (and this provenance line).
26
+ Measured: sizeof(jmp_buf) == sizeof(sigjmp_buf) == 200, _Alignof == 8, on
27
+ x86-64 glibc (a small probe printing sizeof/_Alignof, built and run with the
28
+ host gcc; see test/test_header_abi.rb's SETJMP case for the same values
29
+ checked against the gcc oracle).
30
+ Caution for rubycc users: 7.13.2.1p3 of the C standard leaves the values of
31
+ non-volatile automatic variables modified between setjmp and longjmp
32
+ unspecified if they were changed after the setjmp call. rubycc performs no
33
+ register allocation across calls -- every local is spilled to its stack slot
34
+ on every store -- so in practice such values come back unchanged after a
35
+ longjmp, which is the conservative (safe) side of that rule: rubycc never
36
+ restores a stale value the way an optimizing compiler that shuffled variables
37
+ into registers might. Do not rely on this coincidence; write code that treats
38
+ such variables as unspecified, as the standard requires, and mark anything
39
+ that must survive the jump `volatile`. */
40
+
41
+ #ifndef _RUBYCC_SETJMP_H
42
+ #define _RUBYCC_SETJMP_H
43
+
44
+ /* The opaque saved-context blocks. glibc stores the callee-saved registers,
45
+ stack pointer and program counter (and, for sigjmp_buf, the saved signal
46
+ mask) inside; rubycc reproduces only the measured size and alignment as an
47
+ opaque blob (the char __size[N] arm alongside the aligning scalar), so a
48
+ variable of the type occupies the right space and alignment without copying
49
+ glibc's field layout. Wider on aarch64 (a different register file), which is
50
+ why this header lives in the arch layer. */
51
+ /* One named type, not two anonymous ones. C gives every anonymous union its
52
+ own distinct type, so declaring jmp_buf and sigjmp_buf separately made
53
+ them incompatible: passing a jmp_buf to siglongjmp() was a type error
54
+ here while gcc accepted it, because glibc spells both as arrays of one
55
+ shared tag. Measured: gcc reports sizeof and _Alignof identical for the
56
+ two names (200 and 8 on this target), which is what lets them share a
57
+ definition. Found building google-protobuf's ruby-upb.h, which stores a
58
+ jmp_buf and hands it to siglongjmp(). */
59
+ union __jmp_buf_tag { char __size[200]; long __align; };
60
+ typedef union __jmp_buf_tag jmp_buf[1];
61
+ typedef union __jmp_buf_tag sigjmp_buf[1];
62
+
63
+ int setjmp(jmp_buf __env);
64
+ void longjmp(jmp_buf __env, int __val) __attribute__((__noreturn__));
65
+
66
+ /* BSD/POSIX non-restoring variants (do not save/restore the signal mask). */
67
+ int _setjmp(jmp_buf __env);
68
+ void _longjmp(jmp_buf __env, int __val) __attribute__((__noreturn__));
69
+
70
+ /* POSIX sigsetjmp. glibc exports no plain `sigsetjmp' symbol -- only
71
+ `__sigsetjmp' -- because sigsetjmp must capture its caller's own stack
72
+ frame, so glibc's own <setjmp.h> makes `sigsetjmp' a macro onto
73
+ `__sigsetjmp' rather than a plain function (a documented public-interface
74
+ fact, not glibc source text: measured here by observing that a plain
75
+ `int sigsetjmp(...)' declaration fails to link against glibc, while
76
+ `__sigsetjmp' does). rubycc's header follows that same public contract so
77
+ generated calls resolve against the host libc. */
78
+ int __sigsetjmp(sigjmp_buf __env, int __savemask);
79
+ #define sigsetjmp(__env, __savemask) __sigsetjmp(__env, __savemask)
80
+ void siglongjmp(sigjmp_buf __env, int __val) __attribute__((__noreturn__));
81
+
82
+ #endif /* _RUBYCC_SETJMP_H */
@@ -0,0 +1,163 @@
1
+ /* rubycc bundled <stdint.h>: exact/least/fast-width integer typedefs and their
2
+ limit and constant-suffix macros (ISO C 7.20). Derived from musl's <stdint.h>
3
+ as the declaration shape, with the widths pinned to the x86-64 LP64 ABI
4
+ (measured): intmax_t/intptr_t are `long`, and the fast types are 64-bit on
5
+ glibc but 32-bit on musl -- the one place in this header where the two C
6
+ libraries differ, carried below under __RUBYCC_LIBC_MUSL__ (see the
7
+ preprocessor's LIBCS). ABI switch layer: these widths are arch specific. */
8
+
9
+ #ifndef _RUBYCC_STDINT_H
10
+ #define _RUBYCC_STDINT_H
11
+
12
+ #ifndef _RUBYCC_WCHAR_T
13
+ #define _RUBYCC_WCHAR_T
14
+ typedef int wchar_t;
15
+ #endif
16
+
17
+ typedef signed char int8_t;
18
+ typedef short int16_t;
19
+ typedef int int32_t;
20
+ typedef long int64_t;
21
+ typedef unsigned char uint8_t;
22
+ typedef unsigned short uint16_t;
23
+ typedef unsigned int uint32_t;
24
+ typedef unsigned long uint64_t;
25
+
26
+ typedef signed char int_least8_t;
27
+ typedef short int_least16_t;
28
+ typedef int int_least32_t;
29
+ typedef long int_least64_t;
30
+ typedef unsigned char uint_least8_t;
31
+ typedef unsigned short uint_least16_t;
32
+ typedef unsigned int uint_least32_t;
33
+ typedef unsigned long uint_least64_t;
34
+
35
+ /* The fast types are where the two C libraries part company: [u]int_fast16_t
36
+ and [u]int_fast32_t are 4 bytes, 4-byte aligned on musl and 8 bytes, 8-byte
37
+ aligned on glibc (both sizeof/_Alignof pairs measured with the ABI harness,
38
+ glibc's on this host and musl's on the CI musl run, docs/STEPS.md Step 193).
39
+ The fast8 and fast64 types agree on both. The limit macros further down
40
+ follow these widths rather than restating them. */
41
+ typedef signed char int_fast8_t;
42
+ #if defined(__RUBYCC_LIBC_MUSL__)
43
+ typedef int int_fast16_t;
44
+ typedef int int_fast32_t;
45
+ #else
46
+ typedef long int_fast16_t;
47
+ typedef long int_fast32_t;
48
+ #endif
49
+ typedef long int_fast64_t;
50
+ typedef unsigned char uint_fast8_t;
51
+ #if defined(__RUBYCC_LIBC_MUSL__)
52
+ typedef unsigned int uint_fast16_t;
53
+ typedef unsigned int uint_fast32_t;
54
+ #else
55
+ typedef unsigned long uint_fast16_t;
56
+ typedef unsigned long uint_fast32_t;
57
+ #endif
58
+ typedef unsigned long uint_fast64_t;
59
+
60
+ #ifndef _RUBYCC_INTPTR_T
61
+ #define _RUBYCC_INTPTR_T
62
+ typedef long intptr_t;
63
+ #endif
64
+ #ifndef _RUBYCC_UINTPTR_T
65
+ #define _RUBYCC_UINTPTR_T
66
+ typedef unsigned long uintptr_t;
67
+ #endif
68
+ typedef long intmax_t;
69
+ typedef unsigned long uintmax_t;
70
+
71
+ /* Exact-width limits. */
72
+ #define INT8_MIN (-128)
73
+ #define INT16_MIN (-32768)
74
+ #define INT32_MIN (-2147483647-1)
75
+ #define INT64_MIN (-9223372036854775807L-1)
76
+ #define INT8_MAX (127)
77
+ #define INT16_MAX (32767)
78
+ #define INT32_MAX (2147483647)
79
+ #define INT64_MAX (9223372036854775807L)
80
+ #define UINT8_MAX (255)
81
+ #define UINT16_MAX (65535)
82
+ #define UINT32_MAX (4294967295U)
83
+ #define UINT64_MAX (18446744073709551615UL)
84
+
85
+ /* Least-width limits (same representation as the exact widths here). */
86
+ #define INT_LEAST8_MIN INT8_MIN
87
+ #define INT_LEAST16_MIN INT16_MIN
88
+ #define INT_LEAST32_MIN INT32_MIN
89
+ #define INT_LEAST64_MIN INT64_MIN
90
+ #define INT_LEAST8_MAX INT8_MAX
91
+ #define INT_LEAST16_MAX INT16_MAX
92
+ #define INT_LEAST32_MAX INT32_MAX
93
+ #define INT_LEAST64_MAX INT64_MAX
94
+ #define UINT_LEAST8_MAX UINT8_MAX
95
+ #define UINT_LEAST16_MAX UINT16_MAX
96
+ #define UINT_LEAST32_MAX UINT32_MAX
97
+ #define UINT_LEAST64_MAX UINT64_MAX
98
+
99
+ /* Fast-width limits (fast8 is 8-bit; fast64 is 64-bit on both libcs). The
100
+ fast16/fast32 group is the range of the type selected above: 32-bit on musl,
101
+ so INT_FAST16_MAX/INT_FAST32_MAX are 2147483647 there against glibc's
102
+ 9223372036854775807 (both measured with the ABI harness, glibc's on this host
103
+ and musl's on the CI musl run, docs/STEPS.md Step 193). The MIN and unsigned
104
+ MAX macros are spelled through the same exact-width names, so they follow the
105
+ width rather than being asserted separately. */
106
+ #define INT_FAST8_MIN INT8_MIN
107
+ #if defined(__RUBYCC_LIBC_MUSL__)
108
+ #define INT_FAST16_MIN INT32_MIN
109
+ #define INT_FAST32_MIN INT32_MIN
110
+ #else
111
+ #define INT_FAST16_MIN INT64_MIN
112
+ #define INT_FAST32_MIN INT64_MIN
113
+ #endif
114
+ #define INT_FAST64_MIN INT64_MIN
115
+ #define INT_FAST8_MAX INT8_MAX
116
+ #if defined(__RUBYCC_LIBC_MUSL__)
117
+ #define INT_FAST16_MAX INT32_MAX
118
+ #define INT_FAST32_MAX INT32_MAX
119
+ #else
120
+ #define INT_FAST16_MAX INT64_MAX
121
+ #define INT_FAST32_MAX INT64_MAX
122
+ #endif
123
+ #define INT_FAST64_MAX INT64_MAX
124
+ #define UINT_FAST8_MAX UINT8_MAX
125
+ #if defined(__RUBYCC_LIBC_MUSL__)
126
+ #define UINT_FAST16_MAX UINT32_MAX
127
+ #define UINT_FAST32_MAX UINT32_MAX
128
+ #else
129
+ #define UINT_FAST16_MAX UINT64_MAX
130
+ #define UINT_FAST32_MAX UINT64_MAX
131
+ #endif
132
+ #define UINT_FAST64_MAX UINT64_MAX
133
+
134
+ /* Pointer-holding, greatest-width, and the stddef/wchar companions. */
135
+ #define INTPTR_MIN INT64_MIN
136
+ #define INTPTR_MAX INT64_MAX
137
+ #define UINTPTR_MAX UINT64_MAX
138
+ #define INTMAX_MIN INT64_MIN
139
+ #define INTMAX_MAX INT64_MAX
140
+ #define UINTMAX_MAX UINT64_MAX
141
+ #define PTRDIFF_MIN INT64_MIN
142
+ #define PTRDIFF_MAX INT64_MAX
143
+ #define SIZE_MAX UINT64_MAX
144
+ #define SIG_ATOMIC_MIN INT32_MIN
145
+ #define SIG_ATOMIC_MAX INT32_MAX
146
+ #define WCHAR_MIN INT32_MIN
147
+ #define WCHAR_MAX INT32_MAX
148
+ #define WINT_MIN (0U)
149
+ #define WINT_MAX (4294967295U)
150
+
151
+ /* Constant-expression suffix macros. */
152
+ #define INT8_C(c) c
153
+ #define INT16_C(c) c
154
+ #define INT32_C(c) c
155
+ #define INT64_C(c) c ## L
156
+ #define UINT8_C(c) c
157
+ #define UINT16_C(c) c
158
+ #define UINT32_C(c) c ## U
159
+ #define UINT64_C(c) c ## UL
160
+ #define INTMAX_C(c) c ## L
161
+ #define UINTMAX_C(c) c ## UL
162
+
163
+ #endif /* _RUBYCC_STDINT_H */
@@ -0,0 +1,91 @@
1
+ /* rubycc bundled <sys/epoll.h> (x86-64): the Linux epoll(7) event-notification
2
+ interface. Provenance: clean room against the Linux kernel UAPI
3
+ (linux/eventpoll.h) and the glibc call surface, not derived from musl or
4
+ glibc source. The EPOLL_CTL_ / EPOLL / EPOLL_CLOEXEC values and struct
5
+ epoll_event's layout are that ABI reproduced as measured integer constants
6
+ and measured field offsets (an ABI fact, not copied text -- see
7
+ docs/HEADER-LICENSING.md sec. 4), the same treatment as poll.h and
8
+ sys/socket.h.
9
+
10
+ Arch layer, unlike poll.h: struct epoll_event's layout is the one place in
11
+ this header that differs between the two targets, and it differs by design.
12
+ The kernel fixed the x86-64 epoll_event at 12 bytes so that a 32-bit and a
13
+ 64-bit process see the same array stride, which means the 8-byte-aligned
14
+ epoll_data_t union has to sit at offset 4 -- i.e. the struct is packed.
15
+ Measured with the glibc oracle:
16
+
17
+ x86-64 : sizeof 12, _Alignof 1, events @ 0, data @ 4 (packed)
18
+ aarch64: sizeof 16, _Alignof 8, events @ 0, data @ 8 (not packed)
19
+
20
+ so this header is in the arch layer (like fcntl.h, pthread.h, setjmp.h and
21
+ sys/stat.h) with an aarch64 sibling, rather than in the common layer with a
22
+ preprocessor branch. Every macro value, by contrast, measured identical on
23
+ both targets and is repeated verbatim in the aarch64 copy.
24
+
25
+ epoll_create/epoll_create1/epoll_ctl/epoll_wait are Linux/glibc
26
+ declarations whose bodies resolve from the host libc at link time.
27
+
28
+ Not included: epoll_pwait/epoll_pwait2 (their sigset_t / struct timespec
29
+ parameters would mean cross-including <signal.h> and <time.h>, and no
30
+ corpus census hit needs them -- nio4r and unicorn, the two gems that put
31
+ this header on the list, reach epoll_create/epoll_ctl/epoll_wait only). */
32
+
33
+ #ifndef _RUBYCC_SYS_EPOLL_H
34
+ #define _RUBYCC_SYS_EPOLL_H
35
+
36
+ #include <stdint.h>
37
+
38
+ /* epoll_ctl operations (measured, both arches). */
39
+ #define EPOLL_CTL_ADD 1
40
+ #define EPOLL_CTL_DEL 2
41
+ #define EPOLL_CTL_MOD 3
42
+
43
+ /* epoll_create1 flag; shares O_CLOEXEC's bit (measured, both arches). */
44
+ #define EPOLL_CLOEXEC 0x80000
45
+
46
+ /* Event bits. The first six are the poll(2) values epoll reuses; the top four
47
+ are epoll's own behaviour switches (measured, both arches). EPOLLET does not
48
+ fit a signed int, so it is spelled as the unsigned hex value the oracle
49
+ printed. */
50
+ #define EPOLLIN 0x001
51
+ #define EPOLLPRI 0x002
52
+ #define EPOLLOUT 0x004
53
+ #define EPOLLERR 0x008
54
+ #define EPOLLHUP 0x010
55
+ #define EPOLLRDNORM 0x040
56
+ #define EPOLLRDBAND 0x080
57
+ #define EPOLLWRNORM 0x100
58
+ #define EPOLLWRBAND 0x200
59
+ #define EPOLLMSG 0x400
60
+ #define EPOLLRDHUP 0x2000
61
+ #define EPOLLEXCLUSIVE 0x10000000
62
+ #define EPOLLWAKEUP 0x20000000
63
+ #define EPOLLONESHOT 0x40000000
64
+ #define EPOLLET 0x80000000
65
+
66
+ /* The caller-owned cookie epoll hands back with each ready event: 8 bytes,
67
+ 8-byte aligned (measured, both arches), all four arms at offset 0. */
68
+ union epoll_data {
69
+ void *ptr;
70
+ int fd;
71
+ uint32_t u32;
72
+ uint64_t u64;
73
+ };
74
+
75
+ typedef union epoll_data epoll_data_t;
76
+
77
+ /* struct epoll_event: 12 bytes, 1-byte aligned on x86-64 (measured) -- the
78
+ packed attribute is what pulls `data` back to offset 4 and drops the
79
+ trailing padding, reproducing the kernel's deliberate 12-byte stride. */
80
+ struct epoll_event {
81
+ uint32_t events; /* offset 0: an EPOLL* bit set */
82
+ epoll_data_t data; /* offset 4 (packed) */
83
+ } __attribute__((packed));
84
+
85
+ int epoll_create(int __size);
86
+ int epoll_create1(int __flags);
87
+ int epoll_ctl(int __epfd, int __op, int __fd, struct epoll_event *__event);
88
+ int epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents,
89
+ int __timeout);
90
+
91
+ #endif /* _RUBYCC_SYS_EPOLL_H */
@@ -0,0 +1,19 @@
1
+ /* rubycc bundled <sys/fcntl.h>: the traditional compatibility alias for
2
+ <fcntl.h>. Provenance: clean room -- glibc's own <sys/fcntl.h> is a one-line
3
+ shim (`#include <fcntl.h>`, confirmed by inspecting the host's copy at
4
+ /usr/include/x86_64-linux-gnu/sys/fcntl.h and its aarch64 counterpart,
5
+ which agree byte for byte); nothing else is emitted so there is no ABI
6
+ surface to measure beyond fcntl.h's own (already covered by that header's
7
+ Spec). Placed alongside fcntl.h in the glibc/x86-64 layer (the same
8
+ directory choice fcntl.h itself made, because O_DIRECT/O_DIRECTORY/
9
+ O_NOFOLLOW there swap bit assignments against aarch64) purely for
10
+ directory-structure symmetry with sys/select.h, sys/stat.h, sys/time.h and
11
+ sys/types.h, which already live one per arch even where -- like this file
12
+ -- their content does not differ (Step 124, M5 H2). */
13
+
14
+ #ifndef _RUBYCC_SYS_FCNTL_H
15
+ #define _RUBYCC_SYS_FCNTL_H
16
+
17
+ #include <fcntl.h>
18
+
19
+ #endif /* _RUBYCC_SYS_FCNTL_H */
@@ -0,0 +1,75 @@
1
+ /* rubycc bundled <sys/select.h>: fd_set and select()/pselect() (POSIX). Derived
2
+ from musl's <sys/select.h> shape; fd_set is pinned to the glibc x86-64 ABI --
3
+ __FD_SETSIZE is 1024 and __fd_mask is `long`, giving a 128-byte set (measured).
4
+ The typedef guards reuse glibc's (__sigset_t_defined) so a host <signal.h> on
5
+ the path does not redefine sigset_t. ABI switch layer: FD_SETSIZE and the mask
6
+ width are arch specific. */
7
+
8
+ #ifndef _RUBYCC_SYS_SELECT_H
9
+ #define _RUBYCC_SYS_SELECT_H
10
+
11
+ #ifndef _RUBYCC_TIME_T
12
+ #define _RUBYCC_TIME_T
13
+ typedef long time_t;
14
+ #endif
15
+ #ifndef _RUBYCC_SUSECONDS_T
16
+ #define _RUBYCC_SUSECONDS_T
17
+ typedef long suseconds_t;
18
+ #endif
19
+
20
+ #ifndef __timeval_defined
21
+ #define __timeval_defined 1
22
+ struct timeval {
23
+ time_t tv_sec;
24
+ suseconds_t tv_usec;
25
+ };
26
+ #endif
27
+ #ifndef _STRUCT_TIMESPEC
28
+ #define _STRUCT_TIMESPEC 1
29
+ struct timespec {
30
+ time_t tv_sec;
31
+ long tv_nsec;
32
+ };
33
+ #endif
34
+
35
+ #ifndef __sigset_t_defined
36
+ #define __sigset_t_defined 1
37
+ typedef struct { unsigned long __val[1024 / (8 * sizeof(unsigned long))]; } __sigset_t;
38
+ typedef __sigset_t sigset_t;
39
+ #endif
40
+
41
+ #define __FD_SETSIZE 1024
42
+ typedef long __fd_mask;
43
+ #define __NFDBITS (8 * (int) sizeof(__fd_mask))
44
+
45
+ typedef struct {
46
+ __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
47
+ } fd_set;
48
+
49
+ typedef __fd_mask fd_mask;
50
+
51
+ #define FD_SETSIZE __FD_SETSIZE
52
+
53
+ #define __FD_ELT(d) ((d) / __NFDBITS)
54
+ #define __FD_MASK(d) ((__fd_mask) (1UL << ((d) % __NFDBITS)))
55
+
56
+ #define FD_ZERO(set) \
57
+ do { \
58
+ unsigned long __i; \
59
+ fd_set *__s = (set); \
60
+ for (__i = 0; __i < sizeof(fd_set) / sizeof(__fd_mask); ++__i) \
61
+ __s->__fds_bits[__i] = 0; \
62
+ } while (0)
63
+ #define FD_SET(d, set) ((set)->__fds_bits[__FD_ELT(d)] |= __FD_MASK(d))
64
+ #define FD_CLR(d, set) ((set)->__fds_bits[__FD_ELT(d)] &= ~__FD_MASK(d))
65
+ #define FD_ISSET(d, set) (((set)->__fds_bits[__FD_ELT(d)] & __FD_MASK(d)) != 0)
66
+
67
+ int select(int __nfds, fd_set *__restrict __readfds,
68
+ fd_set *__restrict __writefds, fd_set *__restrict __exceptfds,
69
+ struct timeval *__restrict __timeout);
70
+ int pselect(int __nfds, fd_set *__restrict __readfds,
71
+ fd_set *__restrict __writefds, fd_set *__restrict __exceptfds,
72
+ const struct timespec *__restrict __timeout,
73
+ const sigset_t *__restrict __sigmask);
74
+
75
+ #endif /* _RUBYCC_SYS_SELECT_H */
@@ -0,0 +1,130 @@
1
+ /* rubycc bundled <sys/stat.h>: struct stat and the file-mode macros (POSIX).
2
+ Provenance: clean room against the Linux x86-64 kernel ABI, not derived from
3
+ musl. struct stat is pinned to that ABI: the field order, the __pad0 slot
4
+ before st_rdev, the nanosecond timespec fields and the trailing reserved
5
+ longs give the measured 144-byte layout. Both the layout and the S_IF* octal
6
+ values are ABI facts reproduced by measurement, not copied text (see
7
+ docs/HEADER-LICENSING.md). Placed in the glibc/x86-64 layer because they are
8
+ kernel-ABI specific. */
9
+
10
+ #ifndef _RUBYCC_SYS_STAT_H
11
+ #define _RUBYCC_SYS_STAT_H
12
+
13
+ #ifndef _RUBYCC_DEV_T
14
+ #define _RUBYCC_DEV_T
15
+ typedef unsigned long dev_t;
16
+ #endif
17
+ #ifndef _RUBYCC_INO_T
18
+ #define _RUBYCC_INO_T
19
+ typedef unsigned long ino_t;
20
+ #endif
21
+ #ifndef _RUBYCC_NLINK_T
22
+ #define _RUBYCC_NLINK_T
23
+ typedef unsigned long nlink_t;
24
+ #endif
25
+ #ifndef _RUBYCC_MODE_T
26
+ #define _RUBYCC_MODE_T
27
+ typedef unsigned int mode_t;
28
+ #endif
29
+ #ifndef _RUBYCC_UID_T
30
+ #define _RUBYCC_UID_T
31
+ typedef unsigned int uid_t;
32
+ #endif
33
+ #ifndef _RUBYCC_GID_T
34
+ #define _RUBYCC_GID_T
35
+ typedef unsigned int gid_t;
36
+ #endif
37
+ #ifndef _RUBYCC_OFF_T
38
+ #define _RUBYCC_OFF_T
39
+ typedef long off_t;
40
+ #endif
41
+ #ifndef _RUBYCC_TIME_T
42
+ #define _RUBYCC_TIME_T
43
+ typedef long time_t;
44
+ #endif
45
+ #ifndef _RUBYCC_BLKSIZE_T
46
+ #define _RUBYCC_BLKSIZE_T
47
+ typedef long blksize_t;
48
+ #endif
49
+ #ifndef _RUBYCC_BLKCNT_T
50
+ #define _RUBYCC_BLKCNT_T
51
+ typedef long blkcnt_t;
52
+ #endif
53
+ #ifndef _STRUCT_TIMESPEC
54
+ #define _STRUCT_TIMESPEC 1
55
+ struct timespec {
56
+ time_t tv_sec;
57
+ long tv_nsec;
58
+ };
59
+ #endif
60
+
61
+ struct stat {
62
+ dev_t st_dev;
63
+ ino_t st_ino;
64
+ nlink_t st_nlink;
65
+ mode_t st_mode;
66
+ uid_t st_uid;
67
+ gid_t st_gid;
68
+ int __pad0;
69
+ dev_t st_rdev;
70
+ off_t st_size;
71
+ blksize_t st_blksize;
72
+ blkcnt_t st_blocks;
73
+ struct timespec st_atim;
74
+ struct timespec st_mtim;
75
+ struct timespec st_ctim;
76
+ long __glibc_reserved[3];
77
+ };
78
+
79
+ /* POSIX.1-2008 second-resolution aliases onto the timespec fields. */
80
+ #define st_atime st_atim.tv_sec
81
+ #define st_mtime st_mtim.tv_sec
82
+ #define st_ctime st_ctim.tv_sec
83
+
84
+ /* File type bits (octal, kernel ABI). */
85
+ #define S_IFMT 0170000
86
+ #define S_IFDIR 0040000
87
+ #define S_IFCHR 0020000
88
+ #define S_IFBLK 0060000
89
+ #define S_IFREG 0100000
90
+ #define S_IFIFO 0010000
91
+ #define S_IFLNK 0120000
92
+ #define S_IFSOCK 0140000
93
+
94
+ #define S_ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask))
95
+ #define S_ISDIR(mode) S_ISTYPE((mode), S_IFDIR)
96
+ #define S_ISCHR(mode) S_ISTYPE((mode), S_IFCHR)
97
+ #define S_ISBLK(mode) S_ISTYPE((mode), S_IFBLK)
98
+ #define S_ISREG(mode) S_ISTYPE((mode), S_IFREG)
99
+ #define S_ISFIFO(mode) S_ISTYPE((mode), S_IFIFO)
100
+ #define S_ISLNK(mode) S_ISTYPE((mode), S_IFLNK)
101
+ #define S_ISSOCK(mode) S_ISTYPE((mode), S_IFSOCK)
102
+
103
+ /* Permission bits. */
104
+ #define S_ISUID 04000
105
+ #define S_ISGID 02000
106
+ #define S_ISVTX 01000
107
+ #define S_IRUSR 0400
108
+ #define S_IWUSR 0200
109
+ #define S_IXUSR 0100
110
+ #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
111
+ #define S_IRGRP (S_IRUSR >> 3)
112
+ #define S_IWGRP (S_IWUSR >> 3)
113
+ #define S_IXGRP (S_IXUSR >> 3)
114
+ #define S_IRWXG (S_IRWXU >> 3)
115
+ #define S_IROTH (S_IRGRP >> 3)
116
+ #define S_IWOTH (S_IWGRP >> 3)
117
+ #define S_IXOTH (S_IXGRP >> 3)
118
+ #define S_IRWXO (S_IRWXG >> 3)
119
+
120
+ int stat(const char *__restrict __file, struct stat *__restrict __buf);
121
+ int fstat(int __fd, struct stat *__buf);
122
+ int lstat(const char *__restrict __file, struct stat *__restrict __buf);
123
+ int fstatat(int __fd, const char *__restrict __file, struct stat *__restrict __buf, int __flag);
124
+ int chmod(const char *__file, mode_t __mode);
125
+ int fchmod(int __fd, mode_t __mode);
126
+ int mkdir(const char *__path, mode_t __mode);
127
+ int mkfifo(const char *__path, mode_t __mode);
128
+ mode_t umask(mode_t __mask);
129
+
130
+ #endif /* _RUBYCC_SYS_STAT_H */