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,131 @@
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/aarch64 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 here than on x86-64, so this file differs from the companion
19
+ glibc/x86-64/pthread.h only in those four __size[N] counts (and this
20
+ provenance line).
21
+ musl disagrees with glibc on five of these objects here, one more than the
22
+ x86-64 companion's single case (pthread_rwlockattr_t's alignment): musl's
23
+ pthread_mutex_t is 40 bytes against glibc's 48, its pthread_attr_t 56
24
+ against glibc's 64, its pthread_mutexattr_t and pthread_condattr_t 4 bytes
25
+ against glibc's 8 (all four with the same alignment on both libcs), and its
26
+ pthread_rwlockattr_t is 4-byte aligned against glibc's 8 (same 8-byte size
27
+ on both) -- the opaque pthreads objects are the single most arch-dependent
28
+ thing in this layer, as the four differing __size[N] counts above already
29
+ show, so this file's musl figures are its own measurement rather than the
30
+ x86-64 companion's single-case one, taken on the CI aarch64 musl run
31
+ (docs/STEPS.md Step 202). Every other pthreads object here (pthread_t,
32
+ pthread_cond_t, pthread_rwlock_t and the small scalar handles) measured
33
+ identical on the two libraries. */
34
+
35
+ #ifndef _RUBYCC_PTHREAD_H
36
+ #define _RUBYCC_PTHREAD_H
37
+
38
+ /* The thread handle and the small scalar handles (identical on both arches). */
39
+ typedef unsigned long pthread_t;
40
+ typedef int pthread_once_t;
41
+ typedef unsigned int pthread_key_t;
42
+ typedef int pthread_spinlock_t;
43
+
44
+ /* The opaque pthreads objects. Each carries real internal fields in glibc;
45
+ rubycc reproduces only the measured size and alignment as an opaque blob (the
46
+ char __size[N] arm alongside the aligning scalar), so a variable of the type
47
+ occupies the right space and alignment without copying glibc's field layout.
48
+ pthread_attr_t, pthread_mutex_t, pthread_mutexattr_t and pthread_condattr_t
49
+ have a wider __size[N] on aarch64 (the four counts that differ between the two
50
+ arch layers); the others are identical on both arches.
51
+ Five of these additionally differ by libc on this arch (see the provenance
52
+ note above): pthread_mutex_t, pthread_attr_t, pthread_mutexattr_t and
53
+ pthread_condattr_t are narrower on musl (same alignment as glibc), and
54
+ pthread_rwlockattr_t keeps glibc's 8-byte size but musl's alignment is
55
+ narrower. Both figures measured with the ABI harness, glibc's on this host
56
+ and musl's on the CI aarch64 musl run (docs/STEPS.md Step 202). */
57
+ #if defined(__RUBYCC_LIBC_MUSL__)
58
+ typedef union { char __size[56]; long __align; } pthread_attr_t;
59
+ typedef union { char __size[40]; long __align; } pthread_mutex_t;
60
+ typedef union { char __size[4]; int __align; } pthread_mutexattr_t;
61
+ typedef union { char __size[48]; long __align; } pthread_cond_t;
62
+ typedef union { char __size[4]; int __align; } pthread_condattr_t;
63
+ typedef union { char __size[56]; long __align; } pthread_rwlock_t;
64
+ typedef union { char __size[8]; int __align; } pthread_rwlockattr_t;
65
+ #else
66
+ typedef union { char __size[64]; long __align; } pthread_attr_t;
67
+ typedef union { char __size[48]; long __align; } pthread_mutex_t;
68
+ typedef union { char __size[8]; int __align; } pthread_mutexattr_t;
69
+ typedef union { char __size[48]; long __align; } pthread_cond_t;
70
+ typedef union { char __size[8]; int __align; } pthread_condattr_t;
71
+ typedef union { char __size[56]; long __align; } pthread_rwlock_t;
72
+ typedef union { char __size[8]; long __align; } pthread_rwlockattr_t;
73
+ #endif
74
+
75
+ /* Mutex kinds (pthread_mutexattr_settype / __kind). */
76
+ #define PTHREAD_MUTEX_NORMAL 0
77
+ #define PTHREAD_MUTEX_RECURSIVE 1
78
+ #define PTHREAD_MUTEX_ERRORCHECK 2
79
+ #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
80
+
81
+ /* Detach state (pthread_attr_setdetachstate). */
82
+ #define PTHREAD_CREATE_JOINABLE 0
83
+ #define PTHREAD_CREATE_DETACHED 1
84
+
85
+ /* Process-shared attribute values. */
86
+ #define PTHREAD_PROCESS_PRIVATE 0
87
+ #define PTHREAD_PROCESS_SHARED 1
88
+
89
+ /* Static initializers: zero the first arm of the opaque union. */
90
+ #define PTHREAD_MUTEX_INITIALIZER { { 0 } }
91
+ #define PTHREAD_COND_INITIALIZER { { 0 } }
92
+ #define PTHREAD_RWLOCK_INITIALIZER { { 0 } }
93
+ #define PTHREAD_ONCE_INIT 0
94
+
95
+ int pthread_create(pthread_t *__thread, const pthread_attr_t *__attr, void *(*__start)(void *), void *__arg);
96
+ int pthread_join(pthread_t __thread, void **__retval);
97
+ int pthread_detach(pthread_t __thread);
98
+ pthread_t pthread_self(void);
99
+ int pthread_equal(pthread_t __t1, pthread_t __t2);
100
+ int pthread_kill(pthread_t __thread, int __sig);
101
+ void pthread_exit(void *__retval);
102
+ int pthread_mutex_init(pthread_mutex_t *__mutex, const pthread_mutexattr_t *__attr);
103
+ int pthread_mutex_destroy(pthread_mutex_t *__mutex);
104
+ int pthread_mutex_lock(pthread_mutex_t *__mutex);
105
+ int pthread_mutex_trylock(pthread_mutex_t *__mutex);
106
+ int pthread_mutex_unlock(pthread_mutex_t *__mutex);
107
+ int pthread_cond_init(pthread_cond_t *__cond, const pthread_condattr_t *__attr);
108
+ int pthread_cond_destroy(pthread_cond_t *__cond);
109
+ int pthread_cond_wait(pthread_cond_t *__cond, pthread_mutex_t *__mutex);
110
+ int pthread_cond_signal(pthread_cond_t *__cond);
111
+ int pthread_cond_broadcast(pthread_cond_t *__cond);
112
+ int pthread_once(pthread_once_t *__once, void (*__init)(void));
113
+ int pthread_key_create(pthread_key_t *__key, void (*__destr)(void *));
114
+ int pthread_key_delete(pthread_key_t __key);
115
+ void *pthread_getspecific(pthread_key_t __key);
116
+ int pthread_setspecific(pthread_key_t __key, const void *__value);
117
+ int pthread_attr_init(pthread_attr_t *__attr);
118
+ int pthread_attr_destroy(pthread_attr_t *__attr);
119
+ int pthread_mutexattr_init(pthread_mutexattr_t *__attr);
120
+ int pthread_mutexattr_destroy(pthread_mutexattr_t *__attr);
121
+ int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __type);
122
+
123
+ /* Process-fork hook registration (a process-wide call, unlike the
124
+ thread-manipulation calls above). Declaring this turns stackprof's
125
+ build failure from a compile-time "implicit declaration" error into a
126
+ link-time one: glibc supplies pthread_atfork only from libc_nonshared.a,
127
+ whose member references __dso_handle, which rubycc's linker cannot yet
128
+ resolve (Step 146 gap 6, a separate, unfixed problem). */
129
+ int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void));
130
+
131
+ #endif /* _RUBYCC_PTHREAD_H */
@@ -0,0 +1,84 @@
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/aarch64 layer because the opaque size is arch dependent:
23
+ jmp_buf holds one register set per architecture, so it is wider here than on
24
+ x86-64 (aarch64 saves more callee-saved integer and FP/SIMD registers) -- this
25
+ file differs from the companion glibc/x86-64/setjmp.h only in the __size[N]
26
+ count (and this provenance line).
27
+ Measured: sizeof(jmp_buf) == sizeof(sigjmp_buf) == 312, _Alignof == 8, on
28
+ aarch64 glibc (a small probe printing sizeof/_Alignof, cross-compiled with
29
+ aarch64-linux-gnu-gcc -static and run under qemu-aarch64; see
30
+ test/test_header_abi.rb's SETJMP case run against the cross-gcc oracle for
31
+ the same values).
32
+ Caution for rubycc users: 7.13.2.1p3 of the C standard leaves the values of
33
+ non-volatile automatic variables modified between setjmp and longjmp
34
+ unspecified if they were changed after the setjmp call. rubycc performs no
35
+ register allocation across calls -- every local is spilled to its stack slot
36
+ on every store -- so in practice such values come back unchanged after a
37
+ longjmp, which is the conservative (safe) side of that rule: rubycc never
38
+ restores a stale value the way an optimizing compiler that shuffled variables
39
+ into registers might. Do not rely on this coincidence; write code that treats
40
+ such variables as unspecified, as the standard requires, and mark anything
41
+ that must survive the jump `volatile`. */
42
+
43
+ #ifndef _RUBYCC_SETJMP_H
44
+ #define _RUBYCC_SETJMP_H
45
+
46
+ /* The opaque saved-context blocks. glibc stores the callee-saved registers,
47
+ stack pointer and program counter (and, for sigjmp_buf, the saved signal
48
+ mask) inside; rubycc reproduces only the measured size and alignment as an
49
+ opaque blob (the char __size[N] arm alongside the aligning scalar), so a
50
+ variable of the type occupies the right space and alignment without copying
51
+ glibc's field layout. Wider than on x86-64 (a different register file),
52
+ which is why this header lives in the arch layer. */
53
+ /* One named type, not two anonymous ones. C gives every anonymous union its
54
+ own distinct type, so declaring jmp_buf and sigjmp_buf separately made
55
+ them incompatible: passing a jmp_buf to siglongjmp() was a type error
56
+ here while gcc accepted it, because glibc spells both as arrays of one
57
+ shared tag. Measured: gcc reports sizeof and _Alignof identical for the
58
+ two names (312 and 8 on this target), which is what lets them share a
59
+ definition. Found building google-protobuf's ruby-upb.h, which stores a
60
+ jmp_buf and hands it to siglongjmp(). */
61
+ union __jmp_buf_tag { char __size[312]; long __align; };
62
+ typedef union __jmp_buf_tag jmp_buf[1];
63
+ typedef union __jmp_buf_tag sigjmp_buf[1];
64
+
65
+ int setjmp(jmp_buf __env);
66
+ void longjmp(jmp_buf __env, int __val) __attribute__((__noreturn__));
67
+
68
+ /* BSD/POSIX non-restoring variants (do not save/restore the signal mask). */
69
+ int _setjmp(jmp_buf __env);
70
+ void _longjmp(jmp_buf __env, int __val) __attribute__((__noreturn__));
71
+
72
+ /* POSIX sigsetjmp. glibc exports no plain `sigsetjmp' symbol -- only
73
+ `__sigsetjmp' -- because sigsetjmp must capture its caller's own stack
74
+ frame, so glibc's own <setjmp.h> makes `sigsetjmp' a macro onto
75
+ `__sigsetjmp' rather than a plain function (a documented public-interface
76
+ fact, not glibc source text: measured here by observing that a plain
77
+ `int sigsetjmp(...)' declaration fails to link against glibc, while
78
+ `__sigsetjmp' does). rubycc's header follows that same public contract so
79
+ generated calls resolve against the host libc. */
80
+ int __sigsetjmp(sigjmp_buf __env, int __savemask);
81
+ #define sigsetjmp(__env, __savemask) __sigsetjmp(__env, __savemask)
82
+ void siglongjmp(sigjmp_buf __env, int __val) __attribute__((__noreturn__));
83
+
84
+ #endif /* _RUBYCC_SETJMP_H */
@@ -0,0 +1,174 @@
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 aarch64 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 -- see below. The one ABI difference from the
6
+ x86-64 layer besides the fast types is WCHAR_MIN/WCHAR_MAX: aarch64 makes
7
+ wchar_t unsigned, so the macros are 0 and UINT32_MAX rather than the signed
8
+ INT32_MIN/INT32_MAX. The wchar_t typedef itself is left `typedef int wchar_t`
9
+ (signed): it is shared with the freestanding <stddef.h> through the
10
+ _RUBYCC_WCHAR_T guard, so changing its signedness only here would make the two
11
+ disagree depending on include order. wchar_t's signedness is therefore a known
12
+ limitation (like long double's width); the ABI surface the harness checks --
13
+ the WCHAR_MIN/WCHAR_MAX macro values -- is what is pinned to aarch64 here.
14
+ The fast types are the other place the two C libraries part company, and here
15
+ it is a machine-dependent fact rather than a portable one: on this arch
16
+ [u]int_fast16_t/[u]int_fast32_t are 4 bytes, 4-byte aligned on musl against
17
+ 8 bytes, 8-byte aligned on glibc (both sizeof/_Alignof pairs measured with
18
+ the ABI harness, glibc's on this host and musl's on the CI aarch64 musl run,
19
+ docs/STEPS.md Step 202) -- the same split the x86-64 companion carries, but
20
+ measured here rather than copied from there, since a fast type's width is
21
+ exactly the kind of thing this arch layer exists to keep per-machine (R8).
22
+ The limit macros further down follow these widths rather than restating
23
+ them. ABI switch layer: these widths are arch specific. */
24
+
25
+ #ifndef _RUBYCC_STDINT_H
26
+ #define _RUBYCC_STDINT_H
27
+
28
+ #ifndef _RUBYCC_WCHAR_T
29
+ #define _RUBYCC_WCHAR_T
30
+ typedef int wchar_t;
31
+ #endif
32
+
33
+ typedef signed char int8_t;
34
+ typedef short int16_t;
35
+ typedef int int32_t;
36
+ typedef long int64_t;
37
+ typedef unsigned char uint8_t;
38
+ typedef unsigned short uint16_t;
39
+ typedef unsigned int uint32_t;
40
+ typedef unsigned long uint64_t;
41
+
42
+ typedef signed char int_least8_t;
43
+ typedef short int_least16_t;
44
+ typedef int int_least32_t;
45
+ typedef long int_least64_t;
46
+ typedef unsigned char uint_least8_t;
47
+ typedef unsigned short uint_least16_t;
48
+ typedef unsigned int uint_least32_t;
49
+ typedef unsigned long uint_least64_t;
50
+
51
+ typedef signed char int_fast8_t;
52
+ #if defined(__RUBYCC_LIBC_MUSL__)
53
+ typedef int int_fast16_t;
54
+ typedef int int_fast32_t;
55
+ #else
56
+ typedef long int_fast16_t;
57
+ typedef long int_fast32_t;
58
+ #endif
59
+ typedef long int_fast64_t;
60
+ typedef unsigned char uint_fast8_t;
61
+ #if defined(__RUBYCC_LIBC_MUSL__)
62
+ typedef unsigned int uint_fast16_t;
63
+ typedef unsigned int uint_fast32_t;
64
+ #else
65
+ typedef unsigned long uint_fast16_t;
66
+ typedef unsigned long uint_fast32_t;
67
+ #endif
68
+ typedef unsigned long uint_fast64_t;
69
+
70
+ #ifndef _RUBYCC_INTPTR_T
71
+ #define _RUBYCC_INTPTR_T
72
+ typedef long intptr_t;
73
+ #endif
74
+ #ifndef _RUBYCC_UINTPTR_T
75
+ #define _RUBYCC_UINTPTR_T
76
+ typedef unsigned long uintptr_t;
77
+ #endif
78
+ typedef long intmax_t;
79
+ typedef unsigned long uintmax_t;
80
+
81
+ /* Exact-width limits. */
82
+ #define INT8_MIN (-128)
83
+ #define INT16_MIN (-32768)
84
+ #define INT32_MIN (-2147483647-1)
85
+ #define INT64_MIN (-9223372036854775807L-1)
86
+ #define INT8_MAX (127)
87
+ #define INT16_MAX (32767)
88
+ #define INT32_MAX (2147483647)
89
+ #define INT64_MAX (9223372036854775807L)
90
+ #define UINT8_MAX (255)
91
+ #define UINT16_MAX (65535)
92
+ #define UINT32_MAX (4294967295U)
93
+ #define UINT64_MAX (18446744073709551615UL)
94
+
95
+ /* Least-width limits (same representation as the exact widths here). */
96
+ #define INT_LEAST8_MIN INT8_MIN
97
+ #define INT_LEAST16_MIN INT16_MIN
98
+ #define INT_LEAST32_MIN INT32_MIN
99
+ #define INT_LEAST64_MIN INT64_MIN
100
+ #define INT_LEAST8_MAX INT8_MAX
101
+ #define INT_LEAST16_MAX INT16_MAX
102
+ #define INT_LEAST32_MAX INT32_MAX
103
+ #define INT_LEAST64_MAX INT64_MAX
104
+ #define UINT_LEAST8_MAX UINT8_MAX
105
+ #define UINT_LEAST16_MAX UINT16_MAX
106
+ #define UINT_LEAST32_MAX UINT32_MAX
107
+ #define UINT_LEAST64_MAX UINT64_MAX
108
+
109
+ /* Fast-width limits (fast8 is 8-bit; fast64 is 64-bit on both libcs). The
110
+ fast16/fast32 group is the range of the type selected above: 32-bit on
111
+ musl, so INT_FAST16_MAX/INT_FAST32_MAX are 2147483647 there against
112
+ glibc's 9223372036854775807 (both measured with the ABI harness, glibc's
113
+ on this host and musl's on the CI aarch64 musl run, docs/STEPS.md
114
+ Step 202). The MIN and unsigned MAX macros are spelled through the same
115
+ exact-width names, so they follow the width rather than being asserted
116
+ separately. */
117
+ #define INT_FAST8_MIN INT8_MIN
118
+ #if defined(__RUBYCC_LIBC_MUSL__)
119
+ #define INT_FAST16_MIN INT32_MIN
120
+ #define INT_FAST32_MIN INT32_MIN
121
+ #else
122
+ #define INT_FAST16_MIN INT64_MIN
123
+ #define INT_FAST32_MIN INT64_MIN
124
+ #endif
125
+ #define INT_FAST64_MIN INT64_MIN
126
+ #define INT_FAST8_MAX INT8_MAX
127
+ #if defined(__RUBYCC_LIBC_MUSL__)
128
+ #define INT_FAST16_MAX INT32_MAX
129
+ #define INT_FAST32_MAX INT32_MAX
130
+ #else
131
+ #define INT_FAST16_MAX INT64_MAX
132
+ #define INT_FAST32_MAX INT64_MAX
133
+ #endif
134
+ #define INT_FAST64_MAX INT64_MAX
135
+ #define UINT_FAST8_MAX UINT8_MAX
136
+ #if defined(__RUBYCC_LIBC_MUSL__)
137
+ #define UINT_FAST16_MAX UINT32_MAX
138
+ #define UINT_FAST32_MAX UINT32_MAX
139
+ #else
140
+ #define UINT_FAST16_MAX UINT64_MAX
141
+ #define UINT_FAST32_MAX UINT64_MAX
142
+ #endif
143
+ #define UINT_FAST64_MAX UINT64_MAX
144
+
145
+ /* Pointer-holding, greatest-width, and the stddef/wchar companions. */
146
+ #define INTPTR_MIN INT64_MIN
147
+ #define INTPTR_MAX INT64_MAX
148
+ #define UINTPTR_MAX UINT64_MAX
149
+ #define INTMAX_MIN INT64_MIN
150
+ #define INTMAX_MAX INT64_MAX
151
+ #define UINTMAX_MAX UINT64_MAX
152
+ #define PTRDIFF_MIN INT64_MIN
153
+ #define PTRDIFF_MAX INT64_MAX
154
+ #define SIZE_MAX UINT64_MAX
155
+ #define SIG_ATOMIC_MIN INT32_MIN
156
+ #define SIG_ATOMIC_MAX INT32_MAX
157
+ #define WCHAR_MIN 0
158
+ #define WCHAR_MAX UINT32_MAX
159
+ #define WINT_MIN (0U)
160
+ #define WINT_MAX (4294967295U)
161
+
162
+ /* Constant-expression suffix macros. */
163
+ #define INT8_C(c) c
164
+ #define INT16_C(c) c
165
+ #define INT32_C(c) c
166
+ #define INT64_C(c) c ## L
167
+ #define UINT8_C(c) c
168
+ #define UINT16_C(c) c
169
+ #define UINT32_C(c) c ## U
170
+ #define UINT64_C(c) c ## UL
171
+ #define INTMAX_C(c) c ## L
172
+ #define UINTMAX_C(c) c ## UL
173
+
174
+ #endif /* _RUBYCC_STDINT_H */
@@ -0,0 +1,88 @@
1
+ /* rubycc bundled <sys/epoll.h> (aarch64): 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: this file differs from its x86-64 sibling in
11
+ exactly one place, struct epoll_event's packing. The kernel fixed the
12
+ x86-64 epoll_event at 12 bytes so a 32-bit and a 64-bit process see the
13
+ same array stride, which forces the 8-byte-aligned epoll_data_t to offset
14
+ 4; aarch64 has no 32-bit compat concern of that shape, so the struct is
15
+ laid out naturally. Measured with the cross gcc oracle under qemu:
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
+ Every macro value below measured identical to the x86-64 copy's.
21
+
22
+ epoll_create/epoll_create1/epoll_ctl/epoll_wait are Linux/glibc
23
+ declarations whose bodies resolve from the host libc at link time.
24
+
25
+ Not included: epoll_pwait/epoll_pwait2 (their sigset_t / struct timespec
26
+ parameters would mean cross-including <signal.h> and <time.h>, and no
27
+ corpus census hit needs them -- nio4r and unicorn, the two gems that put
28
+ this header on the list, reach epoll_create/epoll_ctl/epoll_wait only). */
29
+
30
+ #ifndef _RUBYCC_SYS_EPOLL_H
31
+ #define _RUBYCC_SYS_EPOLL_H
32
+
33
+ #include <stdint.h>
34
+
35
+ /* epoll_ctl operations (measured, both arches). */
36
+ #define EPOLL_CTL_ADD 1
37
+ #define EPOLL_CTL_DEL 2
38
+ #define EPOLL_CTL_MOD 3
39
+
40
+ /* epoll_create1 flag; shares O_CLOEXEC's bit (measured, both arches). */
41
+ #define EPOLL_CLOEXEC 0x80000
42
+
43
+ /* Event bits. The first six are the poll(2) values epoll reuses; the top four
44
+ are epoll's own behaviour switches (measured, both arches). EPOLLET does not
45
+ fit a signed int, so it is spelled as the unsigned hex value the oracle
46
+ printed. */
47
+ #define EPOLLIN 0x001
48
+ #define EPOLLPRI 0x002
49
+ #define EPOLLOUT 0x004
50
+ #define EPOLLERR 0x008
51
+ #define EPOLLHUP 0x010
52
+ #define EPOLLRDNORM 0x040
53
+ #define EPOLLRDBAND 0x080
54
+ #define EPOLLWRNORM 0x100
55
+ #define EPOLLWRBAND 0x200
56
+ #define EPOLLMSG 0x400
57
+ #define EPOLLRDHUP 0x2000
58
+ #define EPOLLEXCLUSIVE 0x10000000
59
+ #define EPOLLWAKEUP 0x20000000
60
+ #define EPOLLONESHOT 0x40000000
61
+ #define EPOLLET 0x80000000
62
+
63
+ /* The caller-owned cookie epoll hands back with each ready event: 8 bytes,
64
+ 8-byte aligned (measured, both arches), all four arms at offset 0. */
65
+ union epoll_data {
66
+ void *ptr;
67
+ int fd;
68
+ uint32_t u32;
69
+ uint64_t u64;
70
+ };
71
+
72
+ typedef union epoll_data epoll_data_t;
73
+
74
+ /* struct epoll_event: 16 bytes, 8-byte aligned on aarch64 (measured) -- no
75
+ packed attribute here, so `data` takes its natural offset 8 and the struct
76
+ its natural size, which is where this file parts from the x86-64 copy. */
77
+ struct epoll_event {
78
+ uint32_t events; /* offset 0: an EPOLL* bit set */
79
+ epoll_data_t data; /* offset 8 */
80
+ };
81
+
82
+ int epoll_create(int __size);
83
+ int epoll_create1(int __flags);
84
+ int epoll_ctl(int __epfd, int __op, int __fd, struct epoll_event *__event);
85
+ int epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents,
86
+ int __timeout);
87
+
88
+ #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/aarch64-linux-gnu/include/sys/fcntl.h and its x86-64 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/aarch64 layer (the same
8
+ directory choice fcntl.h itself made, because O_DIRECT/O_DIRECTORY/
9
+ O_NOFOLLOW here swap bit assignments against x86-64) 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 */