nomen-lang 0.5.0 → 0.6.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.
- package/core/System/Arena.nm +6 -6
- package/core/System/Buffer.nm +15 -6
- package/core/System/Channel.nm +2 -0
- package/core/System/ClassBuffer.nm +14 -5
- package/core/System/Controls/Button.nm +2 -2
- package/core/System/Controls/CheckBox.nm +2 -2
- package/core/System/Controls/Container.nm +3 -3
- package/core/System/Controls/TextBox.nm +2 -2
- package/core/System/Fiber.nm +85 -5
- package/core/System/Graph.nm +1 -1
- package/core/System/LinkedList.nm +1 -1
- package/core/System/List.nm +3 -3
- package/core/System/Map.nm +2 -2
- package/core/System/Mutex.nm +8 -8
- package/core/System/Option.nm +2 -2
- package/core/System/Random.nm +67 -0
- package/core/System/Result.nm +2 -2
- package/core/System/Set.nm +1 -1
- package/core/System/Spawnable.nm +18 -0
- package/core/System/Stream/File.nm +3 -3
- package/core/System/Stream/Http.nm +5 -5
- package/core/System/Stream/Tcp.nm +6 -6
- package/core/System/String.nm +7 -7
- package/core/System/StringBuilder.nm +1 -1
- package/core/System/Task.nm +42 -8
- package/core/System/Test.nm +20 -11
- package/core/System/Text/CharIndex.nm +8 -8
- package/core/System/Text/Chars.nm +1 -1
- package/core/System/Text/JsonTree.nm +1 -1
- package/core/System/Text/Regex.nm +122 -32
- package/core/System/Text/Utf8.nm +6 -6
- package/core/System/Thread.nm +118 -2
- package/core/System/Tree.nm +1 -1
- package/dist/index.mjs +1166 -1097
- package/package.json +1 -1
package/core/System/Thread.nm
CHANGED
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
// The pool infrastructure (types, worker loop, submit, shutdown, cancel
|
|
22
22
|
// thread-local) lives in build_spawn_node and is emitted as file-scope C
|
|
23
23
|
// on the first spawn — not in Thread's own methods — so that Thread can be
|
|
24
|
-
// generic without duplicating the pool per instantiation.
|
|
24
|
+
// generic without duplicating the pool per instantiation. The construction
|
|
25
|
+
// (`Thread(fn(args))`, the deferred-call special form) is compiler-emitted;
|
|
26
|
+
// `.start()` / `.detach()` are regular methods over the runtime seam.
|
|
25
27
|
//
|
|
26
28
|
// MUST-START: a Thread value that is destroyed without ever being started
|
|
27
29
|
// is a programming error — #destroy reports it and aborts. start/detach
|
|
@@ -30,10 +32,23 @@
|
|
|
30
32
|
//
|
|
31
33
|
// See ASYNC.md for the design.
|
|
32
34
|
|
|
35
|
+
// The launch surface's return type (ASYNC.md: the dependency is
|
|
36
|
+
// declared by the library file, not inferred from user-source tokens).
|
|
37
|
+
import Task
|
|
38
|
+
|
|
33
39
|
/**
|
|
34
40
|
* A deferred function call, startable on the shared worker pool
|
|
35
41
|
**/
|
|
36
|
-
pub class Thread<T> : Sendable {
|
|
42
|
+
pub class Thread<T> : Sendable, Spawnable<T> {
|
|
43
|
+
// The construction hook (ASYNC.md): declares this class's
|
|
44
|
+
// construction as the deferred-call special form — the single argument
|
|
45
|
+
// is a call (args packed eagerly, call deferred) or a zero-arg function
|
|
46
|
+
// value. The compiler matches this member, never the class name; the
|
|
47
|
+
// construction itself is compiler-generated (pack the args, allocate the
|
|
48
|
+
// future machinery, build the instance), so the body is a declaration.
|
|
49
|
+
#spawn = () {
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
// The packed task closure (a `struct nomen_closure *`); owned by this
|
|
38
53
|
// value until start/detach/nursery.start transfers it to the runtime.
|
|
39
54
|
pub var uint64 task = 0
|
|
@@ -43,6 +58,107 @@ pub class Thread<T> : Sendable {
|
|
|
43
58
|
pub var uint64 future = 0
|
|
44
59
|
// Must-start flag: set by .start() / .detach() / nursery.start.
|
|
45
60
|
pub var started = false
|
|
61
|
+
// LEXICAL NURSERY CAPTURE (ASYNC.md): the tracking slots of the
|
|
62
|
+
// `async` block that lexically encloses the CONSTRUCTION, or 0 when the
|
|
63
|
+
// construction is outside any block. `.start()` registers the future
|
|
64
|
+
// through these stored pointers, so registration follows the scope that
|
|
65
|
+
// created the deferred call — not the one that happens to start it — and
|
|
66
|
+
// works through an indirect receiver. The pointers address the block's
|
|
67
|
+
// own futures list slots (the block cannot exit until every registered
|
|
68
|
+
// task has finished, so a started-before-exit task never registers into
|
|
69
|
+
// dead storage).
|
|
70
|
+
pub var uint64 nursery_futures = 0
|
|
71
|
+
pub var uint64 nursery_count = 0
|
|
72
|
+
pub var uint64 nursery_cap = 0
|
|
73
|
+
|
|
74
|
+
// Start the deferred call on the shared worker pool and yield the
|
|
75
|
+
// Task<T> handle. Consumes the instance's launch machinery (submit, then
|
|
76
|
+
// register with the construction-time nursery, if any) and zeroes the
|
|
77
|
+
// fields, so #destroy becomes a no-op afterwards. The future's refs
|
|
78
|
+
// account for the trampoline, the returned handle, and the nursery (when
|
|
79
|
+
// captured).
|
|
80
|
+
pub func start = (ref self, move out Task<T>) {
|
|
81
|
+
```
|
|
82
|
+
#arch: c
|
|
83
|
+
struct nomen_future *_f = (struct nomen_future *)self->future;
|
|
84
|
+
_f->refs = self->nursery_futures ? 3 : 2;
|
|
85
|
+
__nomen_pool_submit((struct nomen_closure *)self->task);
|
|
86
|
+
if (self->nursery_futures) {
|
|
87
|
+
__nomen_nursery_track((void **)self->nursery_futures, (int *)self->nursery_count, (int *)self->nursery_cap, _f);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
```
|
|
91
|
+
#arch: aarch64
|
|
92
|
+
// x19 = self. f = self->future (#32); nursery_futures at #48.
|
|
93
|
+
ldr x0, [x19, #32]
|
|
94
|
+
ldr x1, [x19, #48]
|
|
95
|
+
mov w2, #2
|
|
96
|
+
cbz x1, .Lnomen_start_refs
|
|
97
|
+
mov w2, #3
|
|
98
|
+
.Lnomen_start_refs:
|
|
99
|
+
str w2, [x0, #116]
|
|
100
|
+
// __nomen_pool_submit(self->task)
|
|
101
|
+
ldr x0, [x19, #8]
|
|
102
|
+
bl ___nomen_pool_submit
|
|
103
|
+
// if (self->nursery_futures) __nomen_nursery_track(futures, count, cap, f)
|
|
104
|
+
ldr x0, [x19, #48]
|
|
105
|
+
cbz x0, .Lnomen_start_notrack
|
|
106
|
+
ldr x1, [x19, #56]
|
|
107
|
+
ldr x2, [x19, #64]
|
|
108
|
+
ldr x3, [x19, #32]
|
|
109
|
+
bl ___nomen_nursery_track
|
|
110
|
+
.Lnomen_start_notrack:
|
|
111
|
+
```
|
|
112
|
+
// The handle is a fresh heap Task built through the internal #init;
|
|
113
|
+
// the caller owns it (a discarded statement form is reclaimed at
|
|
114
|
+
// scope exit, releasing its refs share).
|
|
115
|
+
var t = Task<T>()
|
|
116
|
+
t.result_slot = self.result_slot
|
|
117
|
+
t.cancel_flag = self.cancel_flag
|
|
118
|
+
t.future = self.future
|
|
119
|
+
// Transfer the handles out of the instance: the runtime owns
|
|
120
|
+
// everything now, and #destroy must not touch (or must-start-abort).
|
|
121
|
+
self.task = 0
|
|
122
|
+
self.future = 0
|
|
123
|
+
self.result_slot = 0
|
|
124
|
+
self.cancel_flag = 0
|
|
125
|
+
self.started = true
|
|
126
|
+
return t
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Run the deferred call on a dedicated detached pthread — the daemon
|
|
130
|
+
// form. Never a pool worker, never joined; process exit kills it
|
|
131
|
+
// mid-execution BY DESIGN. The unused future (a Thread always carries
|
|
132
|
+
// the full machinery) is released — first detaching the closure from it,
|
|
133
|
+
// so the daemon runner owns the closure now.
|
|
134
|
+
pub func detach = (ref self) {
|
|
135
|
+
```
|
|
136
|
+
#arch: c
|
|
137
|
+
struct nomen_future *_uf = (struct nomen_future *)self->future;
|
|
138
|
+
if (_uf) {
|
|
139
|
+
_uf->owner_args = NULL;
|
|
140
|
+
__nomen_future_release(_uf);
|
|
141
|
+
}
|
|
142
|
+
__nomen_task_detach((struct nomen_closure *)self->task);
|
|
143
|
+
```
|
|
144
|
+
```
|
|
145
|
+
#arch: aarch64
|
|
146
|
+
// if (self->future) { owner_args = NULL; release it }
|
|
147
|
+
ldr x0, [x19, #32]
|
|
148
|
+
cbz x0, .Lnomen_detach_nofut
|
|
149
|
+
str xzr, [x0, #136]
|
|
150
|
+
bl ___nomen_future_release
|
|
151
|
+
.Lnomen_detach_nofut:
|
|
152
|
+
// __nomen_task_detach(self->task)
|
|
153
|
+
ldr x0, [x19, #8]
|
|
154
|
+
bl ___nomen_task_detach
|
|
155
|
+
```
|
|
156
|
+
self.task = 0
|
|
157
|
+
self.future = 0
|
|
158
|
+
self.result_slot = 0
|
|
159
|
+
self.cancel_flag = 0
|
|
160
|
+
self.started = true
|
|
161
|
+
}
|
|
46
162
|
|
|
47
163
|
// Destroying an unstarted Thread is a programming error (the wrapped
|
|
48
164
|
// call would silently never run) — report it and abort. A started
|
package/core/System/Tree.nm
CHANGED