qr_reader-native 0.0.1

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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-mruby.txt +22 -0
  3. data/LICENSE-spinel.txt +19 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +61 -0
  6. data/ext/qr_reader_native/SPINEL_VERSION +1 -0
  7. data/ext/qr_reader_native/extconf.rb +8 -0
  8. data/ext/qr_reader_native/mruby/error.h +13 -0
  9. data/ext/qr_reader_native/mruby/internal.h +145 -0
  10. data/ext/qr_reader_native/mruby/string.h +22 -0
  11. data/ext/qr_reader_native/mruby.h +93 -0
  12. data/ext/qr_reader_native/mruby_shim.h +118 -0
  13. data/ext/qr_reader_native/qr_reader_native.c +13513 -0
  14. data/ext/qr_reader_native/qr_reader_native.h +29 -0
  15. data/ext/qr_reader_native/qr_reader_native_ext.c +598 -0
  16. data/ext/qr_reader_native/re_cased.h +71 -0
  17. data/ext/qr_reader_native/re_compile.c +5784 -0
  18. data/ext/qr_reader_native/re_ctype.h +3540 -0
  19. data/ext/qr_reader_native/re_exec.c +2190 -0
  20. data/ext/qr_reader_native/re_internal.h +671 -0
  21. data/ext/qr_reader_native/re_prop.h +4629 -0
  22. data/ext/qr_reader_native/re_spinel.c +363 -0
  23. data/ext/qr_reader_native/re_spinel.h +22 -0
  24. data/ext/qr_reader_native/re_spinel_utf8.inc +97 -0
  25. data/ext/qr_reader_native/re_utf8.c +156 -0
  26. data/ext/qr_reader_native/sp_alloc.c +1447 -0
  27. data/ext/qr_reader_native/sp_alloc.h +1196 -0
  28. data/ext/qr_reader_native/sp_argf.h +33 -0
  29. data/ext/qr_reader_native/sp_array.c +1052 -0
  30. data/ext/qr_reader_native/sp_array.h +456 -0
  31. data/ext/qr_reader_native/sp_bigint.c +5826 -0
  32. data/ext/qr_reader_native/sp_bigint.h +117 -0
  33. data/ext/qr_reader_native/sp_cold.c +5259 -0
  34. data/ext/qr_reader_native/sp_compat.h +402 -0
  35. data/ext/qr_reader_native/sp_core.c +818 -0
  36. data/ext/qr_reader_native/sp_core.h +56 -0
  37. data/ext/qr_reader_native/sp_crypto.c +877 -0
  38. data/ext/qr_reader_native/sp_crypto.h +169 -0
  39. data/ext/qr_reader_native/sp_dtoa.c +1533 -0
  40. data/ext/qr_reader_native/sp_dtoa.h +29 -0
  41. data/ext/qr_reader_native/sp_encoding_names.h +172 -0
  42. data/ext/qr_reader_native/sp_enum.h +86 -0
  43. data/ext/qr_reader_native/sp_exc.c +1185 -0
  44. data/ext/qr_reader_native/sp_exc.h +186 -0
  45. data/ext/qr_reader_native/sp_exc_ctx.h +56 -0
  46. data/ext/qr_reader_native/sp_fiber.c +889 -0
  47. data/ext/qr_reader_native/sp_fiber.h +162 -0
  48. data/ext/qr_reader_native/sp_fiber_ctx.h +84 -0
  49. data/ext/qr_reader_native/sp_format.c +695 -0
  50. data/ext/qr_reader_native/sp_format.h +83 -0
  51. data/ext/qr_reader_native/sp_gc.c +1793 -0
  52. data/ext/qr_reader_native/sp_gc.h +762 -0
  53. data/ext/qr_reader_native/sp_hash.c +131 -0
  54. data/ext/qr_reader_native/sp_hash.h +131 -0
  55. data/ext/qr_reader_native/sp_inspect.c +215 -0
  56. data/ext/qr_reader_native/sp_inspect.h +128 -0
  57. data/ext/qr_reader_native/sp_io.c +1676 -0
  58. data/ext/qr_reader_native/sp_io.h +272 -0
  59. data/ext/qr_reader_native/sp_iobuffer.c +1014 -0
  60. data/ext/qr_reader_native/sp_iobuffer.h +167 -0
  61. data/ext/qr_reader_native/sp_marshal.c +487 -0
  62. data/ext/qr_reader_native/sp_marshal.h +60 -0
  63. data/ext/qr_reader_native/sp_net.c +1029 -0
  64. data/ext/qr_reader_native/sp_net.h +205 -0
  65. data/ext/qr_reader_native/sp_pack.c +1254 -0
  66. data/ext/qr_reader_native/sp_poly_cold.c +1220 -0
  67. data/ext/qr_reader_native/sp_proc.c +410 -0
  68. data/ext/qr_reader_native/sp_proc.h +327 -0
  69. data/ext/qr_reader_native/sp_process.c +547 -0
  70. data/ext/qr_reader_native/sp_process_status.c +211 -0
  71. data/ext/qr_reader_native/sp_process_status.h +66 -0
  72. data/ext/qr_reader_native/sp_random.c +287 -0
  73. data/ext/qr_reader_native/sp_random.h +52 -0
  74. data/ext/qr_reader_native/sp_range.h +144 -0
  75. data/ext/qr_reader_native/sp_re.c +1379 -0
  76. data/ext/qr_reader_native/sp_re.h +186 -0
  77. data/ext/qr_reader_native/sp_re_names.h +59 -0
  78. data/ext/qr_reader_native/sp_sched.c +4044 -0
  79. data/ext/qr_reader_native/sp_sched.h +295 -0
  80. data/ext/qr_reader_native/sp_slab.c +1507 -0
  81. data/ext/qr_reader_native/sp_str.c +1462 -0
  82. data/ext/qr_reader_native/sp_str.h +306 -0
  83. data/ext/qr_reader_native/sp_str_crypt.c +23 -0
  84. data/ext/qr_reader_native/sp_string.c +92 -0
  85. data/ext/qr_reader_native/sp_string.h +253 -0
  86. data/ext/qr_reader_native/sp_system.c +78 -0
  87. data/ext/qr_reader_native/sp_system.h +18 -0
  88. data/ext/qr_reader_native/sp_time.c +860 -0
  89. data/ext/qr_reader_native/sp_time.h +100 -0
  90. data/ext/qr_reader_native/sp_types.h +292 -0
  91. data/ext/qr_reader_native/spinel_rt.h +19017 -0
  92. data/ext/qr_reader_native/unicase.c +399 -0
  93. data/ext/qr_reader_native/unicase.h +901 -0
  94. data/lib/qr_reader/native.rb +6 -0
  95. metadata +153 -0
@@ -0,0 +1,162 @@
1
+ /* sp_fiber.h -- Fiber runtime surface.
2
+ *
3
+ * The sp_Fiber struct (a cooperative coroutine) is shared between the generated
4
+ * translation unit and lib/sp_fiber.c, which holds the function bodies. The
5
+ * context switch lives in sp_fiber_ctx.h (a portable asm switch on x86_64 /
6
+ * aarch64, ucontext elsewhere) -- no <ucontext.h> here, so OpenBSD compiles.
7
+ * `storage` is an opaque pointer to fiber-local variable storage. */
8
+ #ifndef SP_FIBER_H
9
+ #define SP_FIBER_H
10
+
11
+ #include "sp_gc.h" /* sp_RbVal */
12
+ #include "sp_fiber_ctx.h"
13
+
14
+
15
+ /* A green thread's whole C stack: the build-time default, 256 KB (half of
16
+ CRuby's machine stack for a fiber). The mapping is virtual space until a
17
+ page is touched, so what a fiber costs is the depth it actually reaches,
18
+ not this number; what it bounds is how deep a call chain, or how large a
19
+ frame, a fiber can run (#4496). The size a program runs with is
20
+ sp_fiber_stack_size, settable at run time: SPINEL_FIBER_STACK=<bytes>
21
+ (K/M suffixes) in the environment wins, else the hint the generated
22
+ program gives (an unoptimised build asks for more, its frames being many
23
+ times -O2's), else this default. */
24
+ #ifndef SP_FIBER_STACK_SIZE
25
+ #define SP_FIBER_STACK_SIZE (256*1024)
26
+ #endif
27
+ extern size_t sp_fiber_stack_size;
28
+ /* the generated program's request, honoured unless the environment says otherwise */
29
+ void sp_fiber_stack_hint(size_t bytes);
30
+ /* The PROT_NONE guard below it. One page catches a frame that grows past the
31
+ stack a page at a time, and nothing else: a C compiler that emits no stack
32
+ probes (gcc on Linux, by default) lets a 51 KB frame step straight over a
33
+ 4 KB guard into whatever mapping sits below, and the program runs on with
34
+ that mapping corrupted (#4496). The guard is virtual space only, never
35
+ touched, so it is sized to the largest frame a build is likely to emit
36
+ rather than to a page; a frame larger than this still has to be probed. */
37
+ #ifndef SP_FIBER_GUARD_SIZE
38
+ #define SP_FIBER_GUARD_SIZE (256*1024)
39
+ #endif
40
+
41
+ /* ThreadSanitizer support: the asm context switch swaps stacks without TSan's
42
+ knowledge, so a fiber program reports spurious "unexpected memory mapping"
43
+ or false races. Under -fsanitize=thread we give each fiber a TSan fiber
44
+ handle and call __tsan_switch_to_fiber at every swap so TSan follows the
45
+ cooperative switch. SP_TSAN is set only in that build (a separate archive),
46
+ so the fiber struct carries the two extra fields only there -- the archive
47
+ and the generated TU agree because both are compiled with -fsanitize=thread. */
48
+ #ifndef __has_feature /* gcc lacks __has_feature; clang has it */
49
+ #define __has_feature(x) 0
50
+ #endif
51
+ #if defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer)
52
+ #define SP_TSAN 1
53
+ #endif
54
+
55
+ typedef struct sp_Fiber{sp_fiber_ctx ctx;sp_fiber_ctx caller_ctx;char*stack;size_t stack_size;int state;int transferred;sp_RbVal yielded_value;sp_RbVal resumed_value;void(*body)(struct sp_Fiber*);void*user_data;int saved_exc_top;int saved_catch_top;void*exc_ctx;int raised;const char*raised_cls;const char*raised_msg;void*raised_obj;int inject;int inject_defer;const char*inj_cls;const char*inj_msg;void*inj_obj;void*storage;void*attrs;/* per-fiber attributes (Fiber.attr_accessor): a table of the fiber's own, never copied into a new fiber as `storage` is */void***saved_roots;int saved_nroots;int saved_roots_cap;struct sp_Fiber*fiber_next;struct sp_Fiber*fiber_prev;struct sp_Fiber*resumer;/* the fiber suspended inside #resume of this one, until it returns: the chain from the running fiber back to the root is what the collector roots; every other suspended fiber lives by reference (#4525) */const char*birth_file;sp_int birth_line;int pass_argc;unsigned owner;/* id + 1 of the thread that made it (#6110); 0: no owner */struct sp_Fiber*return_to;/* where it goes if it ends after a transfer: the innermost fiber still inside a resume (NULL: the thread's main fiber) */unsigned char thread_main;/* a Thread's own fiber (its main fiber) */unsigned char blocking;/* Fiber.new(blocking: true), or inside Fiber.blocking { } *//* how many values the first resume passed (-1: not known), so |a| can tell resume(1, 2) from resume([1, 2]) *//* the Fiber.new site, for #inspect */
56
+ #ifdef SP_TSAN
57
+ void *tsan_fiber; /* __tsan fiber handle for this coroutine */
58
+ struct sp_Fiber *caller_fiber; /* who switched into us (the swap-out target) */
59
+ #endif
60
+ }sp_Fiber;
61
+
62
+ /* The currently-running fiber; the generated TU reads it directly for
63
+ `Fiber.current` and as the implicit receiver of Fiber operations. Per-worker
64
+ (SP_TLS) in the threaded build so each worker tracks the green thread it runs;
65
+ the generated TU is compiled with the matching -DSP_THREADS. (The scheduler
66
+ root fiber it is initialized to stays a shared static until per-worker root
67
+ fibers land with the workers.) */
68
+ extern SP_TLS sp_Fiber *sp_fiber_current;
69
+
70
+ /* Adopt the calling OS thread's root fiber (its native scheduler stack) as its
71
+ current coroutine, and read that per-worker root back. Worker 0 calls
72
+ sp_fiber_worker_init from sp_sched_init; helper workers from their startup. In
73
+ the single-threaded build the root is a shared static and these are inert. */
74
+ void sp_fiber_worker_init(void);
75
+ sp_Fiber *sp_fiber_worker_root(void);
76
+ /* Switch from a green thread back to the fiber that ran it, without the
77
+ checks Fiber#transfer makes (that fiber may be one the main thread resumed). */
78
+ void sp_fiber_sched_switch(sp_Fiber *f);
79
+ /* Publish the running worker's shadow-stack roots into its current green thread
80
+ (for a stop-the-world collector to mark while the worker is parked). */
81
+ void sp_fiber_publish_current_roots(void);
82
+ /* Mark a fiber's published (saved) roots; used by the collector to reach a
83
+ parked worker's root fiber, which is not on the global fiber list. */
84
+ void sp_fiber_mark_roots(sp_Fiber *f);
85
+ void sp_fiber_mark_chain(sp_Fiber *f); /* f and every resumer waiting on it (#4525) */
86
+
87
+ /* Public Fiber API (called from the generated TU). */
88
+ sp_Fiber *sp_Fiber_new(void (*body)(sp_Fiber *));
89
+ sp_RbVal sp_Fiber_resume(sp_Fiber *f, sp_RbVal val);
90
+ sp_RbVal sp_Fiber_yield(sp_RbVal val);
91
+ unsigned sp_thread_owner_id(void); /* lib/sp_sched.c */
92
+ sp_Fiber *sp_thread_main_fiber(void); /* lib/sp_sched.c */
93
+ /* The fiber a green thread switches back to: the one that ran it on this
94
+ worker, else the worker's root. */
95
+ sp_Fiber *sp_sched_home_fiber(void); /* lib/sp_sched.c */
96
+ sp_RbVal sp_Fiber_resume_n(sp_Fiber *f, sp_RbVal val, int argc);
97
+ sp_RbVal sp_Fiber_transfer_n(sp_Fiber *f, sp_RbVal val, int argc);
98
+ sp_RbVal sp_Fiber_transfer(sp_Fiber *f, sp_RbVal val);
99
+ /* Like sp_Fiber_transfer, but captures f's unhandled termination exception into
100
+ the out-params (for the thread scheduler) instead of re-raising it. When
101
+ f's thread stopped inside a Fiber it resumed, `at` is that fiber and the
102
+ switch goes there (NULL: to f). */
103
+ sp_RbVal sp_Fiber_transfer_catch(sp_Fiber *f, sp_Fiber *at, sp_RbVal val, int *out_raised,
104
+ const char **out_cls, const char **out_msg, void **out_obj);
105
+ /* Fiber#raise: inject an exception at the fiber's suspension point (or at entry
106
+ for an unstarted fiber). cls/msg describe a class+message; obj, when non-NULL,
107
+ is a pre-built exception object to raise instead. Returns the next yielded
108
+ value, or re-raises in the caller if the fiber does not handle it. */
109
+ sp_RbVal sp_Fiber_raise(sp_Fiber *f, const char *cls, const char *msg, void *obj);
110
+ /* Fiber#kill: terminate the fiber (running its ensure blocks); returns it. */
111
+ sp_Fiber *sp_Fiber_kill(sp_Fiber *f);
112
+ sp_bool sp_Fiber_alive(sp_Fiber *f);
113
+ sp_bool sp_Fiber_blocking_p(sp_Fiber *f); /* #blocking? */
114
+ sp_Fiber *sp_Fiber_at(sp_Fiber *f, const char *file, sp_int line);
115
+ const char *sp_Fiber_inspect(sp_Fiber *f); /* #inspect / #to_s */
116
+ sp_RbVal sp_Fiber_storage_get(sp_Fiber *f, sp_sym k);
117
+ void sp_Fiber_storage_set(sp_Fiber *f, sp_sym k, sp_RbVal v);
118
+ void sp_Fiber_storage_put(sp_Fiber *f, sp_sym k, sp_RbVal v);
119
+ sp_int sp_Fiber_storage_len(sp_Fiber *f);
120
+ sp_sym sp_Fiber_storage_key(sp_Fiber *f, sp_int i);
121
+ sp_RbVal sp_Fiber_storage_val(sp_Fiber *f, sp_int i);
122
+ void sp_Fiber_storage_clear(sp_Fiber *f);
123
+ void sp_Fiber_storage_empty(sp_Fiber *f);
124
+ sp_RbVal sp_Fiber_attr_get(sp_Fiber *f, sp_sym k);
125
+ void sp_Fiber_attr_set(sp_Fiber *f, sp_sym k, sp_RbVal v);
126
+ /* Reached from sp_re_mark_globals in the generated TU during a GC pass. */
127
+ void sp_mark_fiber_root_storage(void);
128
+
129
+ /* Thread #kill / #raise: the scheduler queues a pending inject on a target
130
+ fiber, then fires it when that thread next runs (in its own context). */
131
+ void sp_fiber_set_raise_inject(sp_Fiber *f, const char *cls, const char *msg, void *obj);
132
+ void sp_fiber_set_kill_inject(sp_Fiber *f);
133
+ /* ConditionVariable waits defer async delivery until their mutex is reacquired. */
134
+ void sp_fiber_defer_inject(void);
135
+ void sp_fiber_undefer_inject(void);
136
+ void sp_fiber_fire_inject_if_pending(void);
137
+ int sp_fiber_inject_pending(sp_Fiber *f); /* lock-free acquire peek */
138
+ SP_NORETURN void sp_fiber_raise_kill_self(void);
139
+
140
+ /* A C stack that ran out is CRuby's SystemStackError, and a program that
141
+ rescues it goes on running. The raise cannot live here: the exception
142
+ stack is thread-local state in the generated translation unit, which this
143
+ archive is compiled without. The generated TU installs this hook, and the
144
+ fault handler calls it instead of reporting and dying -- on the alternate
145
+ signal stack, so the raise runs on memory the overflow did not touch.
146
+ NULL (nothing installed, or no handler armed) keeps the old report. */
147
+ extern void (*sp_stack_overflow_raise_fn)(void);
148
+ void sp_sig_unblock(int a, int b);
149
+ void sp_stack_guard_init(void);
150
+ /* Run the program body on a stack this library maps (see sp_main_stack_run);
151
+ sp_main_stack_hint asks for a size, SPINEL_MAIN_STACK in the environment
152
+ wins over it. */
153
+ void sp_main_stack_hint(size_t bytes);
154
+ void sp_main_stack_run(void (*body)(void));
155
+
156
+ /* The running thread's own stack, for the fault handler's overflow test: a
157
+ fault just below `lo` is this stack growing past its end. Recorded per
158
+ thread when the handler is armed. */
159
+ extern SP_TLS char *sp_thread_stack_lo;
160
+ extern SP_TLS char *sp_thread_stack_hi;
161
+
162
+ #endif
@@ -0,0 +1,84 @@
1
+ /* sp_fiber_ctx.h -- portable coroutine context switch for sp_fiber.c.
2
+ *
3
+ * Replaces POSIX <ucontext.h> (getcontext/makecontext/swapcontext), which
4
+ * OpenBSD removed in 5.7 (W^X / ASLR hardening) and which is deprecated on
5
+ * macOS. On x86_64 and aarch64 we use a tiny cooperative register switch
6
+ * written as file-scope inline asm (defined in sp_fiber.c): it lands in .text
7
+ * (W^X-safe, unlike libco's executable data blob), does no syscall (unlike
8
+ * swapcontext's sigprocmask, so it's faster), and only saves the callee-saved
9
+ * registers + stack pointer. The "context" is therefore just the saved stack
10
+ * pointer; all other state lives on the coroutine's own stack. Other
11
+ * architectures fall back to <ucontext.h>.
12
+ *
13
+ * sp_ctx_swap(from, to) save the current context into *from,
14
+ * then switch to *to.
15
+ * sp_ctx_make(ctx, base, size, entry) prime a fresh context so the first swap
16
+ * into it begins executing entry() on the
17
+ * stack [base, base+size). entry must
18
+ * never return.
19
+ */
20
+ #ifndef SP_FIBER_CTX_H
21
+ #define SP_FIBER_CTX_H
22
+
23
+ #include <stddef.h>
24
+ #include <stdint.h>
25
+
26
+ /* Windows takes the ucontext fallback, which lib/win32 provides: its x64
27
+ ABI saves more registers, and a switch there also moves the stack bounds
28
+ the thread's TEB holds. */
29
+ #if (defined(__x86_64__) || defined(__aarch64__)) && !defined(_WIN32)
30
+ #define SP_FIBER_ASM 1
31
+ #else
32
+ #define SP_FIBER_ASM 0
33
+ #endif
34
+
35
+ #if SP_FIBER_ASM
36
+
37
+ /* The whole machine context is the saved stack pointer; the callee-saved
38
+ registers are pushed onto / popped from the coroutine's own stack by
39
+ sp_ctx_swap (see the file-scope asm in sp_fiber.c). */
40
+ typedef struct sp_fiber_ctx { void *sp; } sp_fiber_ctx;
41
+
42
+ static inline void sp_ctx_make(sp_fiber_ctx *ctx, void *base, size_t size,
43
+ void (*entry)(void)) {
44
+ uintptr_t top = ((uintptr_t)base + size) & ~(uintptr_t)15; /* 16B-align the top */
45
+ #if defined(__x86_64__)
46
+ /* SysV AMD64: entry's first instruction needs rsp%16 == 8 (as if reached by
47
+ `call`). sp_ctx_swap pops 6 callee-saved regs then `ret`s into the slot
48
+ just above them: [entry][rbp][rbx][r12][r13][r14][r15<-sp]. */
49
+ void **s = (void **)(top - 8);
50
+ *--s = (void *)entry; /* `ret` target, at top-16 */
51
+ for (int i = 0; i < 6; i++) *--s = 0; /* rbp, rbx, r12, r13, r14, r15 */
52
+ ctx->sp = s; /* top-64 */
53
+ #else /* __aarch64__ */
54
+ /* Mirror the aarch64 sp_ctx_swap frame: 160 bytes holding x19..x30 (12) then
55
+ d8..d15 (8). x30 (lr = entry) sits at offset 88 (slot 11). On the first
56
+ swap the ldp's load zeros + entry into lr and `ret` (br x30) jumps to it. */
57
+ void **s = (void **)(top - 160);
58
+ for (int i = 0; i < 20; i++) s[i] = 0;
59
+ s[11] = (void *)entry; /* x30 (lr) */
60
+ ctx->sp = s;
61
+ #endif
62
+ }
63
+
64
+ #else /* portable fallback: POSIX ucontext */
65
+
66
+ #include <ucontext.h>
67
+ typedef struct sp_fiber_ctx { ucontext_t uc; } sp_fiber_ctx;
68
+
69
+ static inline void sp_ctx_make(sp_fiber_ctx *ctx, void *base, size_t size,
70
+ void (*entry)(void)) {
71
+ getcontext(&ctx->uc);
72
+ ctx->uc.uc_stack.ss_sp = base;
73
+ ctx->uc.uc_stack.ss_size = size;
74
+ ctx->uc.uc_link = NULL; /* entry never returns (trampoline switches) */
75
+ makecontext(&ctx->uc, entry, 0);
76
+ }
77
+
78
+ #endif
79
+
80
+ /* Defined as file-scope asm in sp_fiber.c (asm backend) or a swapcontext
81
+ wrapper (fallback). */
82
+ void sp_ctx_swap(sp_fiber_ctx *from, sp_fiber_ctx *to);
83
+
84
+ #endif /* SP_FIBER_CTX_H */