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,83 @@
1
+ /* rubycc bundled <locale.h>: localization (ISO C11 7.11). Provenance: clean
2
+ room against the POSIX/C11 public interface -- struct lconv's member names,
3
+ types and order are the standard's own public contract (C11 7.11.1.1 fixes
4
+ the sequence "the following members ... in the order shown"), not glibc
5
+ implementation detail, so reproducing them is not a glibc derivation. Unlike
6
+ the opaque-blob types elsewhere in this tree (pthread_t, jmp_buf), every
7
+ member of struct lconv is used directly by callers, so it cannot be an
8
+ opaque byte blob; instead its size and every member's offset were measured
9
+ and confirmed against the glibc oracle (see test/test_header_abi.rb's LOCALE
10
+ case). The LC_* category numbers are glibc runtime ABI (setlocale is
11
+ answered by the host libc, so the numbers must match the host's own
12
+ enumeration, the same reasoning as unistd.h's _SC_* constants) and were
13
+ measured rather than invented. setlocale/localeconv are POSIX/ISO C
14
+ declarations whose bodies resolve from the host libc at link time.
15
+ Common layer: measured on both x86-64 and aarch64 glibc (both LP64), and
16
+ struct lconv's size (96) and every member offset agreed exactly across the
17
+ two arches (an all-pointer-and-char struct has no arch-dependent field
18
+ widths on either LP64 target), so this header is arch-neutral, unlike
19
+ pthread.h/setjmp.h/sys/stat.h.
20
+ Not included: glibc's locale_t / newlocale / uselocale / freelocale /
21
+ duplocale extensions. No corpus sample census hit needs them, so they are
22
+ left out to keep the surface to what is actually used (bigdecimal's use of
23
+ struct lconv via localeconv). */
24
+
25
+ #ifndef _RUBYCC_LOCALE_H
26
+ #define _RUBYCC_LOCALE_H
27
+
28
+ #ifndef NULL
29
+ #define NULL ((void*)0)
30
+ #endif
31
+
32
+ /* setlocale's category argument. Measured against glibc (matches the host's
33
+ own __LC_* enumeration, since setlocale resolves from the host libc). */
34
+ #define LC_CTYPE 0
35
+ #define LC_NUMERIC 1
36
+ #define LC_TIME 2
37
+ #define LC_COLLATE 3
38
+ #define LC_MONETARY 4
39
+ #define LC_MESSAGES 5
40
+ #define LC_ALL 6
41
+ #define LC_PAPER 7
42
+ #define LC_NAME 8
43
+ #define LC_ADDRESS 9
44
+ #define LC_TELEPHONE 10
45
+ #define LC_MEASUREMENT 11
46
+ #define LC_IDENTIFICATION 12
47
+
48
+ /* The numeric/monetary formatting conventions localeconv() reports. Member
49
+ names, types and order are the C11 7.11.1.1 public contract; every offset
50
+ below was measured against the glibc oracle on both x86-64 and aarch64 and
51
+ the two agreed byte for byte. */
52
+ struct lconv {
53
+ char *decimal_point;
54
+ char *thousands_sep;
55
+ char *grouping;
56
+
57
+ char *int_curr_symbol;
58
+ char *currency_symbol;
59
+ char *mon_decimal_point;
60
+ char *mon_thousands_sep;
61
+ char *mon_grouping;
62
+ char *positive_sign;
63
+ char *negative_sign;
64
+ char int_frac_digits;
65
+ char frac_digits;
66
+ char p_cs_precedes;
67
+ char p_sep_by_space;
68
+ char n_cs_precedes;
69
+ char n_sep_by_space;
70
+ char p_sign_posn;
71
+ char n_sign_posn;
72
+ char int_p_cs_precedes;
73
+ char int_p_sep_by_space;
74
+ char int_n_cs_precedes;
75
+ char int_n_sep_by_space;
76
+ char int_p_sign_posn;
77
+ char int_n_sign_posn;
78
+ };
79
+
80
+ char *setlocale(int __category, const char *__locale);
81
+ struct lconv *localeconv(void);
82
+
83
+ #endif /* _RUBYCC_LOCALE_H */
@@ -0,0 +1,191 @@
1
+ /* rubycc bundled <math.h>: the floating-point declarations and classification
2
+ macros (ISO C 7.12). Derived from musl's <math.h> declaration set; the special
3
+ values and classifiers are expressed through the compiler builtins so they
4
+ fold to the same bit patterns gcc uses, and the FP_* / math_errhandling values
5
+ are measured (math_errhandling is the one the two C libraries differ on, so
6
+ both values are carried under __RUBYCC_LIBC_MUSL__; see the preprocessor's
7
+ LIBCS). Common layer: nothing here is arch specific beyond the (universal on
8
+ the hosted targets' IEEE 754 model; the two target libc ABIs select their
9
+ distinct FP_ILOGB* values below. */
10
+
11
+ #ifndef _RUBYCC_MATH_H
12
+ #define _RUBYCC_MATH_H
13
+
14
+ /* Special magnitudes. rubycc does not implement gcc's __builtin_huge_val/inf/nan
15
+ family, so these use the classic overflow-literal and 0/0 spellings, which
16
+ both toolchains fold to the same IEEE 754 infinity / quiet-NaN bit patterns
17
+ (verified against gcc). */
18
+ #define HUGE_VAL (1e10000)
19
+ #define HUGE_VALF (1e10000f)
20
+ #define HUGE_VALL (1e10000L)
21
+ #define INFINITY (1e10000f)
22
+ #define NAN (0.0f / 0.0f)
23
+
24
+ /* Classification result codes (glibc values). */
25
+ #define FP_NAN 0
26
+ #define FP_INFINITE 1
27
+ #define FP_ZERO 2
28
+ #define FP_SUBNORMAL 3
29
+ #define FP_NORMAL 4
30
+
31
+ /* glibc's AArch64 math ABI uses -2147483647 for FP_ILOGB0 and INT_MAX for
32
+ FP_ILOGBNAN; glibc's x86-64 uses INT_MIN for both. These are header ABI
33
+ values, not compiler implementation details, so select them from the target
34
+ macro just as float.h and the arch libc headers do.
35
+
36
+ musl uses INT_MIN for both on *every* machine, so the C library has to be
37
+ part of the selection and not only the architecture. Branching on the machine
38
+ alone was wrong exactly where the two disagree -- AArch64 musl, where this
39
+ header claimed glibc's pair (measured against Alpine's own gcc on an arm64
40
+ container, 2026-08-12, the first time the suite ran there). x86-64 musl agreed
41
+ with glibc by coincidence, which is why the x86-64 musl runs never caught
42
+ it. */
43
+ #if defined(__RUBYCC_LIBC_MUSL__)
44
+ #define FP_ILOGB0 (-2147483647-1)
45
+ #define FP_ILOGBNAN (-2147483647-1)
46
+ #elif defined(__aarch64__)
47
+ #define FP_ILOGB0 (-2147483647)
48
+ #define FP_ILOGBNAN (2147483647)
49
+ #else
50
+ #define FP_ILOGB0 (-2147483647-1)
51
+ #define FP_ILOGBNAN (-2147483647-1)
52
+ #endif
53
+
54
+ #define MATH_ERRNO 1
55
+ #define MATH_ERREXCEPT 2
56
+ /* math_errhandling is the one value in this header the two C libraries
57
+ disagree on: musl reports 2 (it raises the floating-point exceptions but
58
+ does not promise errno) where glibc reports 3 (both). Measured with the ABI
59
+ harness, glibc's on this host and musl's on the CI musl run (docs/STEPS.md
60
+ Step 193); MATH_ERRNO, MATH_ERREXCEPT, the FP_* codes and FP_ILOGB* are
61
+ probed too; the FP_ILOGB* values are target-specific as documented above. */
62
+ #if defined(__RUBYCC_LIBC_MUSL__)
63
+ #define math_errhandling (MATH_ERREXCEPT)
64
+ #else
65
+ #define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
66
+ #endif
67
+
68
+ /* Classifiers, implemented in C (rubycc has no __builtin_isnan/signbit/...).
69
+ The bit-inspecting helpers cover the double-or-narrower case; long double is
70
+ an 8-byte double on this target, so the double helper handles it too. */
71
+ static inline int __rubycc_signbit(double __x) {
72
+ union { double __d; unsigned long __u; } __v; __v.__d = __x;
73
+ return (int) (__v.__u >> 63);
74
+ }
75
+ static inline int __rubycc_fpclassify(double __x) {
76
+ union { double __d; unsigned long __u; } __v; __v.__d = __x;
77
+ unsigned long __exp = (__v.__u >> 52) & 0x7ffUL;
78
+ unsigned long __mant = __v.__u & 0xfffffffffffffUL;
79
+ if (__exp == 0) return __mant == 0 ? FP_ZERO : FP_SUBNORMAL;
80
+ if (__exp == 0x7ffUL) return __mant == 0 ? FP_INFINITE : FP_NAN;
81
+ return FP_NORMAL;
82
+ }
83
+
84
+ #define fpclassify(x) __rubycc_fpclassify((double)(x))
85
+ #define isnan(x) ((x) != (x))
86
+ #define isinf(x) (!isnan((double)(x)) && ((x) == HUGE_VAL || (x) == -HUGE_VAL))
87
+ #define isfinite(x) (((x) - (x)) == 0)
88
+ #define isnormal(x) (fpclassify(x) == FP_NORMAL)
89
+ #define signbit(x) __rubycc_signbit((double)(x))
90
+ #define isgreater(x, y) ((x) > (y))
91
+ #define isgreaterequal(x, y) ((x) >= (y))
92
+ #define isless(x, y) ((x) < (y))
93
+ #define islessequal(x, y) ((x) <= (y))
94
+ #define islessgreater(x, y) ((x) < (y) || (x) > (y))
95
+ #define isunordered(x, y) (isnan(x) || isnan(y))
96
+
97
+ /* Common mathematical constants (glibc, under _DEFAULT_SOURCE). */
98
+ #define M_E 2.7182818284590452354
99
+ #define M_LOG2E 1.4426950408889634074
100
+ #define M_LOG10E 0.43429448190325182765
101
+ #define M_LN2 0.69314718055994530942
102
+ #define M_LN10 2.30258509299404568402
103
+ #define M_PI 3.14159265358979323846
104
+ #define M_PI_2 1.57079632679489661923
105
+ #define M_PI_4 0.78539816339744830962
106
+ #define M_1_PI 0.31830988618379067154
107
+ #define M_2_PI 0.63661977236758134308
108
+ #define M_2_SQRTPI 1.12837916709551257390
109
+ #define M_SQRT2 1.41421356237309504880
110
+ #define M_SQRT1_2 0.70710678118654752440
111
+
112
+ typedef float float_t;
113
+ typedef double double_t;
114
+
115
+ /* Double, float and long-double declarations for the standard functions. */
116
+ #define __RUBYCC_MATHDECL(name) \
117
+ double name(double); float name##f(float); long double name##l(long double);
118
+ #define __RUBYCC_MATHDECL2(name) \
119
+ double name(double, double); float name##f(float, float); \
120
+ long double name##l(long double, long double);
121
+
122
+ __RUBYCC_MATHDECL(acos)
123
+ __RUBYCC_MATHDECL(asin)
124
+ __RUBYCC_MATHDECL(atan)
125
+ __RUBYCC_MATHDECL2(atan2)
126
+ __RUBYCC_MATHDECL(cos)
127
+ __RUBYCC_MATHDECL(sin)
128
+ __RUBYCC_MATHDECL(tan)
129
+ __RUBYCC_MATHDECL(cosh)
130
+ __RUBYCC_MATHDECL(sinh)
131
+ __RUBYCC_MATHDECL(tanh)
132
+ __RUBYCC_MATHDECL(acosh)
133
+ __RUBYCC_MATHDECL(asinh)
134
+ __RUBYCC_MATHDECL(atanh)
135
+ __RUBYCC_MATHDECL(exp)
136
+ __RUBYCC_MATHDECL(exp2)
137
+ __RUBYCC_MATHDECL(expm1)
138
+ __RUBYCC_MATHDECL(log)
139
+ __RUBYCC_MATHDECL(log10)
140
+ __RUBYCC_MATHDECL(log1p)
141
+ __RUBYCC_MATHDECL(log2)
142
+ __RUBYCC_MATHDECL(logb)
143
+ __RUBYCC_MATHDECL(cbrt)
144
+ __RUBYCC_MATHDECL(sqrt)
145
+ __RUBYCC_MATHDECL2(pow)
146
+ __RUBYCC_MATHDECL2(hypot)
147
+ __RUBYCC_MATHDECL(ceil)
148
+ __RUBYCC_MATHDECL(fabs)
149
+ __RUBYCC_MATHDECL(floor)
150
+ __RUBYCC_MATHDECL2(fmod)
151
+ __RUBYCC_MATHDECL(round)
152
+ __RUBYCC_MATHDECL(trunc)
153
+ __RUBYCC_MATHDECL(rint)
154
+ __RUBYCC_MATHDECL(nearbyint)
155
+ __RUBYCC_MATHDECL2(remainder)
156
+ __RUBYCC_MATHDECL2(copysign)
157
+ __RUBYCC_MATHDECL2(nextafter)
158
+ __RUBYCC_MATHDECL2(fdim)
159
+ __RUBYCC_MATHDECL2(fmax)
160
+ __RUBYCC_MATHDECL2(fmin)
161
+ __RUBYCC_MATHDECL(tgamma)
162
+ __RUBYCC_MATHDECL(lgamma)
163
+ __RUBYCC_MATHDECL(erf)
164
+ __RUBYCC_MATHDECL(erfc)
165
+
166
+ double frexp(double, int *);
167
+ float frexpf(float, int *);
168
+ long double frexpl(long double, int *);
169
+ double ldexp(double, int);
170
+ float ldexpf(float, int);
171
+ long double ldexpl(long double, int);
172
+ double modf(double, double *);
173
+ float modff(float, float *);
174
+ long double modfl(long double, long double *);
175
+ double scalbn(double, int);
176
+ float scalbnf(float, int);
177
+ long double scalbnl(long double, int);
178
+ double scalbln(double, long);
179
+ double fma(double, double, double);
180
+ float fmaf(float, float, float);
181
+ long double fmal(long double, long double, long double);
182
+ double nan(const char *);
183
+ float nanf(const char *);
184
+ long double nanl(const char *);
185
+ int ilogb(double);
186
+ long lround(double);
187
+ long long llround(double);
188
+ long lrint(double);
189
+ long long llrint(double);
190
+
191
+ #endif /* _RUBYCC_MATH_H */
@@ -0,0 +1,126 @@
1
+ /* rubycc bundled <netinet/in.h>: the IPv4/IPv6 address types, the
2
+ sockaddr_in / sockaddr_in6 structs, the IPPROTO_* protocol numbers and the
3
+ INADDR_* well-known addresses. Provenance: clean room against the Linux
4
+ kernel UAPI (linux/in.h, linux/in6.h) and the glibc socket ABI, not derived
5
+ from musl -- the same treatment as sys/socket.h (see docs/HEADER-LICENSING.md).
6
+ The struct layouts and the IPPROTO_/INADDR_ integer values below are that ABI
7
+ reproduced as measured field offsets and measured integer constants, an ABI
8
+ fact rather than copied text. Common layer: every struct layout (sockaddr_in,
9
+ sockaddr_in6, in6_addr all included) and every macro value is identical on
10
+ x86-64 and aarch64.
11
+
12
+ Shares its address-type definitions with <arpa/inet.h> (in_addr_t, in_port_t,
13
+ struct in_addr, socklen_t) and its address-family type with <sys/socket.h>
14
+ (sa_family_t): each is guarded so whichever header is #included first wins
15
+ and the other's guard short-circuits, so #including both in either order
16
+ never redefines anything. htons/htonl/ntohs/ntohl are declared again here
17
+ with the identical signature <arpa/inet.h> uses -- a repeated declaration of
18
+ the same C function is legal and the two headers commonly get both
19
+ #included by real code (this file needs them for the sockaddr_in field
20
+ assignments a socket client/server writes). */
21
+
22
+ #ifndef _RUBYCC_NETINET_IN_H
23
+ #define _RUBYCC_NETINET_IN_H
24
+
25
+ #include <stdint.h>
26
+
27
+ #ifndef _RUBYCC_SOCKLEN_T
28
+ #define _RUBYCC_SOCKLEN_T
29
+ typedef unsigned int socklen_t;
30
+ #endif
31
+
32
+ #ifndef _RUBYCC_IN_ADDR_T
33
+ #define _RUBYCC_IN_ADDR_T
34
+ typedef uint32_t in_addr_t;
35
+ #endif
36
+
37
+ #ifndef _RUBYCC_IN_PORT_T
38
+ #define _RUBYCC_IN_PORT_T
39
+ typedef uint16_t in_port_t;
40
+ #endif
41
+
42
+ #ifndef _RUBYCC_STRUCT_IN_ADDR
43
+ #define _RUBYCC_STRUCT_IN_ADDR
44
+ struct in_addr { in_addr_t s_addr; };
45
+ #endif
46
+
47
+ #ifndef _RUBYCC_SA_FAMILY_T
48
+ #define _RUBYCC_SA_FAMILY_T
49
+ typedef unsigned short sa_family_t;
50
+ #endif
51
+
52
+ /* IPv6 address: 16 bytes, 4-byte aligned (measured, both arches). The union
53
+ gives access at three widths (glibc's in6_u); s6_addr is the POSIX-visible
54
+ byte-array name, macro'd onto the byte member of the union. */
55
+ struct in6_addr {
56
+ union {
57
+ uint8_t __u6_addr8[16];
58
+ uint16_t __u6_addr16[8];
59
+ uint32_t __u6_addr32[4];
60
+ } __in6_u;
61
+ };
62
+ #define s6_addr __in6_u.__u6_addr8
63
+
64
+ /* struct sockaddr_in: 16 bytes, 4-byte aligned (measured, both arches), the
65
+ IPv4-specific socket address. */
66
+ struct sockaddr_in {
67
+ sa_family_t sin_family; /* offset 0 */
68
+ in_port_t sin_port; /* offset 2 */
69
+ struct in_addr sin_addr; /* offset 4 */
70
+ unsigned char sin_zero[8]; /* offset 8 */
71
+ };
72
+
73
+ /* struct sockaddr_in6: 28 bytes, 4-byte aligned (measured, both arches), the
74
+ IPv6-specific socket address. */
75
+ struct sockaddr_in6 {
76
+ sa_family_t sin6_family; /* offset 0 */
77
+ in_port_t sin6_port; /* offset 2 */
78
+ uint32_t sin6_flowinfo; /* offset 4 */
79
+ struct in6_addr sin6_addr; /* offset 8 */
80
+ uint32_t sin6_scope_id; /* offset 24 */
81
+ };
82
+
83
+ /* IP protocol numbers (Linux kernel UAPI, linux/in.h). */
84
+ #define IPPROTO_IP 0
85
+ #define IPPROTO_ICMP 1
86
+ #define IPPROTO_TCP 6
87
+ #define IPPROTO_UDP 17
88
+ #define IPPROTO_IPV6 41
89
+ #define IPPROTO_RAW 255
90
+
91
+ /* Well-known IPv4 addresses (host byte order, glibc's in_addr_t-typed constants). */
92
+ #define INADDR_ANY ((in_addr_t)0x00000000)
93
+ #define INADDR_LOOPBACK ((in_addr_t)0x7f000001)
94
+ #define INADDR_BROADCAST ((in_addr_t)0xffffffff)
95
+ #define INADDR_NONE ((in_addr_t)0xffffffff)
96
+
97
+ /* Buffer sizes for inet_ntop's textual forms, counting the terminating NUL:
98
+ "255.255.255.255" and the longest IPv6 spelling (an IPv4-mapped address with
99
+ a scope, "ffff:...:255.255.255.255%4294967295"). Measured, and identical on
100
+ x86-64 and aarch64. */
101
+ #define INET_ADDRSTRLEN 16
102
+ #define INET6_ADDRSTRLEN 46
103
+
104
+ /* Well-known IPv6 addresses, as struct in6_addr initializers (glibc's
105
+ IN6ADDR_*_INIT macros); the triple brace reaches through struct in6_addr's
106
+ anonymous union member down to the byte array. */
107
+ #define IN6ADDR_ANY_INIT \
108
+ { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }
109
+ #define IN6ADDR_LOOPBACK_INIT \
110
+ { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } } }
111
+
112
+ /* The same two addresses as objects the host libc defines (measured: both are
113
+ real exported symbols, `V in6addr_any` / `V in6addr_loopback`). A program
114
+ that needs the *address* of one -- raindrops' linux_inet_diag.c memcmps
115
+ against &in6addr_any -- cannot use the initializer macros, so the
116
+ declarations have to be here for the definitions to resolve at link time. */
117
+ extern const struct in6_addr in6addr_any;
118
+ extern const struct in6_addr in6addr_loopback;
119
+
120
+ /* Host<->network byte-order conversions (same declarations as <arpa/inet.h>). */
121
+ uint32_t htonl(uint32_t __hostlong);
122
+ uint16_t htons(uint16_t __hostshort);
123
+ uint32_t ntohl(uint32_t __netlong);
124
+ uint16_t ntohs(uint16_t __netshort);
125
+
126
+ #endif /* _RUBYCC_NETINET_IN_H */
@@ -0,0 +1,44 @@
1
+ /* rubycc bundled <netinet/tcp.h>: the TCP-level setsockopt/getsockopt option
2
+ names (used with level IPPROTO_TCP). Provenance: clean room against the Linux
3
+ kernel UAPI (linux/tcp.h), not derived from musl. The TCP_* values are that
4
+ ABI reproduced as measured integer constants (an ABI fact, not copied text --
5
+ see docs/HEADER-LICENSING.md), the same treatment as errno.h and fcntl.h.
6
+ Common layer: every value is identical on x86-64 and aarch64. The large
7
+ struct tcp_info diagnostic block is deliberately omitted -- gems reach this
8
+ header for the option names (TCP_NODELAY and kin), not that struct. */
9
+
10
+ #ifndef _RUBYCC_NETINET_TCP_H
11
+ #define _RUBYCC_NETINET_TCP_H
12
+
13
+ #define TCP_NODELAY 1
14
+ #define TCP_MAXSEG 2
15
+ #define TCP_CORK 3
16
+ #define TCP_KEEPIDLE 4
17
+ #define TCP_KEEPINTVL 5
18
+ #define TCP_KEEPCNT 6
19
+ #define TCP_INFO 11
20
+ #define TCP_QUICKACK 12
21
+ #define TCP_USER_TIMEOUT 18
22
+ #define TCP_FASTOPEN 23
23
+
24
+ /* The TCP state machine's states, as reported by TCP_INFO's tcpi_state and by
25
+ the kernel's inet_diag netlink replies. glibc spells them as an anonymous
26
+ enum and then #defines each name to itself, so a program can test one with
27
+ #ifdef; plain object macros are indistinguishable from that and are what the
28
+ rest of this header already uses. Measured, and identical on x86-64 and
29
+ aarch64. raindrops' linux_inet_diag.c compares idiag_state against
30
+ TCP_ESTABLISHED and TCP_LISTEN to split active connections from the listen
31
+ queue. */
32
+ #define TCP_ESTABLISHED 1
33
+ #define TCP_SYN_SENT 2
34
+ #define TCP_SYN_RECV 3
35
+ #define TCP_FIN_WAIT1 4
36
+ #define TCP_FIN_WAIT2 5
37
+ #define TCP_TIME_WAIT 6
38
+ #define TCP_CLOSE 7
39
+ #define TCP_CLOSE_WAIT 8
40
+ #define TCP_LAST_ACK 9
41
+ #define TCP_LISTEN 10
42
+ #define TCP_CLOSING 11
43
+
44
+ #endif /* _RUBYCC_NETINET_TCP_H */
@@ -0,0 +1,46 @@
1
+ /* rubycc bundled <poll.h>: the poll(2) event macros and struct pollfd (POSIX).
2
+ Provenance: clean room against the Linux kernel UAPI (asm-generic/poll.h),
3
+ not derived from musl. The POLL* values are the kernel ABI, reproduced here
4
+ as measured integer constants (an ABI fact, not copied text -- see
5
+ docs/HEADER-LICENSING.md), the same treatment as errno.h and fcntl.h. struct
6
+ pollfd is a POSIX declaration. Common layer: struct pollfd's layout and every
7
+ POLLIN/POLLOUT/... value are identical on x86-64 and aarch64, unlike
8
+ fcntl.h's O_DIRECT family. */
9
+
10
+ #ifndef _RUBYCC_POLL_H
11
+ #define _RUBYCC_POLL_H
12
+
13
+ #ifndef _RUBYCC_NFDS_T
14
+ #define _RUBYCC_NFDS_T
15
+ typedef unsigned long nfds_t;
16
+ #endif
17
+
18
+ /* struct pollfd: 8 bytes, 4-byte aligned (measured, both arches). */
19
+ struct pollfd {
20
+ int fd;
21
+ short events;
22
+ short revents;
23
+ };
24
+
25
+ /* Event bits (Linux kernel UAPI, asm-generic/poll.h). POSIX. */
26
+ #define POLLIN 0x001
27
+ #define POLLPRI 0x002
28
+ #define POLLOUT 0x004
29
+ #define POLLERR 0x008
30
+ #define POLLHUP 0x010
31
+ #define POLLNVAL 0x020
32
+
33
+ /* XOPEN extensions. */
34
+ #define POLLRDNORM 0x040
35
+ #define POLLRDBAND 0x080
36
+ #define POLLWRNORM 0x100
37
+ #define POLLWRBAND 0x200
38
+ #define POLLMSG 0x400
39
+
40
+ /* Linux extensions. */
41
+ #define POLLREMOVE 0x1000
42
+ #define POLLRDHUP 0x2000
43
+
44
+ int poll(struct pollfd *__fds, nfds_t __nfds, int __timeout);
45
+
46
+ #endif /* _RUBYCC_POLL_H */
@@ -0,0 +1,58 @@
1
+ /* rubycc bundled <pwd.h>: the user database access interface (POSIX.1 9.2.2).
2
+ Provenance: clean room against the POSIX public interface -- struct passwd's
3
+ member names, types and order are POSIX's own public contract, not glibc
4
+ implementation detail, so reproducing them is not a glibc derivation. Every
5
+ member is used directly by callers, so it cannot be an opaque byte blob;
6
+ instead its size and every member's offset were measured against the glibc
7
+ oracle on both x86-64 and aarch64 (see test/test_header_abi.rb's PWD case)
8
+ and the two agreed exactly (an all-pointer/uid_t/gid_t struct has no
9
+ arch-dependent field widths on either LP64 target), so this header lives in
10
+ the common layer. uid_t/gid_t reuse the shared _RUBYCC_* guards sys/types.h
11
+ and unistd.h also carry. getpwnam/getpwuid/getpwent/setpwent/endpwent/
12
+ getpwnam_r/getpwuid_r are POSIX declarations whose bodies resolve from the
13
+ host libc at link time (getpwnam_r/getpwuid_r answer through NSS, so their
14
+ result is a host runtime fact, not something rubycc computes).
15
+ Not included: fgetpwent/putpwent/getpw (glibc/BSD extensions no corpus
16
+ sample census hit needs), left out to keep the surface to what etc's use of
17
+ getpwnam/getpwuid actually requires (Step 123, M5 H2). */
18
+
19
+ #ifndef _RUBYCC_PWD_H
20
+ #define _RUBYCC_PWD_H
21
+
22
+ #ifndef _RUBYCC_SIZE_T
23
+ #define _RUBYCC_SIZE_T
24
+ typedef unsigned long size_t;
25
+ #endif
26
+ #ifndef _RUBYCC_UID_T
27
+ #define _RUBYCC_UID_T
28
+ typedef unsigned int uid_t;
29
+ #endif
30
+ #ifndef _RUBYCC_GID_T
31
+ #define _RUBYCC_GID_T
32
+ typedef unsigned int gid_t;
33
+ #endif
34
+
35
+ /* A record in the user database. Member names, types and order are the
36
+ POSIX.1 public contract; every offset below was measured against the glibc
37
+ oracle on both x86-64 and aarch64 and the two agreed byte for byte. */
38
+ struct passwd {
39
+ char *pw_name; /* Username. */
40
+ char *pw_passwd; /* Hashed passphrase (if no shadow database). */
41
+ uid_t pw_uid; /* User ID. */
42
+ gid_t pw_gid; /* Group ID. */
43
+ char *pw_gecos; /* Real name. */
44
+ char *pw_dir; /* Home directory. */
45
+ char *pw_shell; /* Shell program. */
46
+ };
47
+
48
+ struct passwd *getpwnam(const char *__name);
49
+ struct passwd *getpwuid(uid_t __uid);
50
+ struct passwd *getpwent(void);
51
+ void setpwent(void);
52
+ void endpwent(void);
53
+ int getpwnam_r(const char *__restrict __name, struct passwd *__restrict __resultbuf,
54
+ char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result);
55
+ int getpwuid_r(uid_t __uid, struct passwd *__restrict __resultbuf,
56
+ char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result);
57
+
58
+ #endif /* _RUBYCC_PWD_H */
@@ -0,0 +1,53 @@
1
+ /* Clean-room ABI subset: rubycc bundled <regex.h> exposes the POSIX
2
+ regular-expression ABI used by C
3
+ extensions such as oj. The public regex_t layout is part of glibc's ABI;
4
+ the implementation behind regcomp/regexec remains the host libc. */
5
+
6
+ #ifndef _RUBYCC_REGEX_H
7
+ #define _RUBYCC_REGEX_H
8
+
9
+ #include <stddef.h>
10
+
11
+ typedef unsigned long reg_syntax_t;
12
+
13
+ struct re_dfa_t;
14
+ struct re_pattern_buffer {
15
+ struct re_dfa_t *buffer;
16
+ unsigned long allocated;
17
+ unsigned long used;
18
+ reg_syntax_t syntax;
19
+ char *fastmap;
20
+ unsigned char *translate;
21
+ size_t re_nsub;
22
+ unsigned can_be_null : 1;
23
+ unsigned regs_allocated : 2;
24
+ unsigned fastmap_accurate : 1;
25
+ unsigned no_sub : 1;
26
+ unsigned not_bol : 1;
27
+ unsigned not_eol : 1;
28
+ unsigned newline_anchor : 1;
29
+ };
30
+ typedef struct re_pattern_buffer regex_t;
31
+
32
+ typedef int regoff_t;
33
+ typedef struct {
34
+ regoff_t rm_so;
35
+ regoff_t rm_eo;
36
+ } regmatch_t;
37
+
38
+ #define REG_EXTENDED 1
39
+ #define REG_ICASE (1 << 1)
40
+ #define REG_NEWLINE (1 << 2)
41
+ #define REG_NOSUB (1 << 3)
42
+ #define REG_NOTBOL 1
43
+ #define REG_NOTEOL (1 << 1)
44
+ #define REG_STARTEND (1 << 2)
45
+
46
+ int regcomp(regex_t *__preg, const char *__pattern, int __cflags);
47
+ int regexec(const regex_t *__preg, const char *__string, size_t __nmatch,
48
+ regmatch_t *__pmatch, int __eflags);
49
+ size_t regerror(int __errcode, const regex_t *__preg, char *__errbuf,
50
+ size_t __errbuf_size);
51
+ void regfree(regex_t *__preg);
52
+
53
+ #endif /* _RUBYCC_REGEX_H */
@@ -0,0 +1,35 @@
1
+ /* rubycc bundled <sched.h>: scheduling (POSIX.1), pared down to the surface
2
+ etc and google-protobuf's corpus samples actually reach (sched_yield,
3
+ sched_getcpu, and cpu_set_t's existence) rather than glibc's full affinity
4
+ API, per Step 123's (M5 H2) explicit scope. Provenance: clean room against
5
+ the glibc/Linux ABI. cpu_set_t is glibc-internal state (a bitmap of
6
+ CPU_SETSIZE bits used only through the CPU_SET/CPU_ZERO/CPU_ISSET macro
7
+ family, none of which any corpus sample census hit needs), so, like
8
+ pthread.h's opaque objects and setjmp.h's jmp_buf, rubycc reproduces only
9
+ its measured size and alignment as an opaque byte blob -- a union of a
10
+ char __size[N] arm and the aligning scalar -- and does not name glibc's
11
+ internal __bits array. That size/alignment (128, 8-byte aligned) was
12
+ measured against the glibc oracle on both x86-64 and aarch64 (see
13
+ test/test_header_abi.rb's SCHED case) and the two agreed exactly (both are
14
+ LP64, so CPU_SETSIZE/8 bytes of bitmap has no arch-dependent width), so
15
+ this header lives in the common layer. sched_yield/sched_getcpu are POSIX/
16
+ glibc declarations whose bodies resolve from the host libc at link time.
17
+ Not included: sched_setaffinity/sched_getaffinity/CPU_SET/CPU_ZERO/
18
+ CPU_ISSET and the sched_setscheduler family (no corpus sample census hit
19
+ needs them; adding the affinity macros would require reproducing
20
+ glibc-internal bit-numbering, not just an opaque size). */
21
+
22
+ #ifndef _RUBYCC_SCHED_H
23
+ #define _RUBYCC_SCHED_H
24
+
25
+ #define CPU_SETSIZE 1024
26
+
27
+ /* Opaque CPU affinity bitmap. glibc stores CPU_SETSIZE bits inside as an
28
+ array of unsigned long words; rubycc reproduces only the measured size and
29
+ alignment as an opaque blob, not the internal word layout. */
30
+ typedef union { char __size[128]; long __align; } cpu_set_t;
31
+
32
+ int sched_yield(void);
33
+ int sched_getcpu(void);
34
+
35
+ #endif /* _RUBYCC_SCHED_H */