• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kos-lang / kos / 28804370359

06 Jul 2026 01:33PM UTC coverage: 95.093% (-1.3%) from 96.422%
28804370359

push

github

cdragan
net: use poll() instead of select()

select() has a limit of 1024 fd values, for any fds which are higher
than 1024 select() can't work.

7 of 13 new or added lines in 1 file covered. (53.85%)

884 existing lines in 19 files now uncovered.

24707 of 25982 relevant lines covered (95.09%)

939477.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.26
/core/kos_buffer.c
1
/* SPDX-License-Identifier: MIT
2
 * SPDX-FileCopyrightText: Copyright (c) 2014-2026 Chris Dragan
3
 */
4

5
#include "../inc/kos_buffer.h"
6
#include "../inc/kos_constants.h"
7
#include "../inc/kos_error.h"
8
#include "../inc/kos_utils.h"
9
#include "kos_heap.h"
10
#include "kos_math.h"
11
#include "kos_misc.h"
12
#include "kos_object_internal.h"
13
#include <string.h>
14

15
KOS_DECLARE_STATIC_CONST_STRING(str_err_empty,            "cannot modify empty buffer");
16
KOS_DECLARE_STATIC_CONST_STRING(str_err_external_storage, "buffer with external storage has fixed capacity");
17
KOS_DECLARE_STATIC_CONST_STRING(str_err_make_room_size,   "buffer size limit exceeded");
18
KOS_DECLARE_STATIC_CONST_STRING(str_err_not_buffer,       "object is not a buffer");
19
KOS_DECLARE_STATIC_CONST_STRING(str_err_read_only,        "buffer is read-only");
20

21
#define KOS_buffer_alloc_size(cap) (sizeof(KOS_BUFFER_STORAGE) + ((cap) - 1U))
22

23
static KOS_BUFFER_STORAGE *alloc_buffer(KOS_CONTEXT ctx, uint32_t capacity)
3,757✔
24
{
25
    KOS_BUFFER_STORAGE *const data = (KOS_BUFFER_STORAGE *)
26
            kos_alloc_object(ctx,
3,757✔
27
                             KOS_ALLOC_MOVABLE,
28
                             OBJ_BUFFER_STORAGE,
29
                             KOS_buffer_alloc_size(capacity));
30

31
#ifndef NDEBUG
32
    /*
33
     * The caller is supposed to fill it out completely and reliably.
34
     * Therefore in debug builds, we fill it with random data to trigger
35
     * any bugs more easily.
36
     */
37
    if (data && capacity) {
3,757✔
38
        static struct KOS_RNG rng;
39
        static int            init = 0;
40
        uint64_t             *buf = (uint64_t *)&data->buf[0];
3,709✔
41
        uint64_t             *end = (uint64_t *)((intptr_t)buf + capacity);
3,709✔
42

43
        assert(kos_get_object_type(data->header) == OBJ_BUFFER_STORAGE);
3,709✔
44

45
        if ( ! init) {
3,709✔
46
            kos_rng_init(&rng);
170✔
47
            init = 1;
170✔
48
        }
49

50
        /* Cheat, reuse ctx_mutex to ensure the RNG is not banged from
51
         * multiple threads. */
52
        kos_lock_mutex(ctx->inst->threads.ctx_mutex);
3,709✔
53

54
        while (((intptr_t)buf & 7) && buf < end) {
3,709✔
55
            *(uint8_t *)buf = (uint8_t)kos_rng_random(&rng);
×
UNCOV
56
            buf = (uint64_t *)((intptr_t)buf + 1);
×
57
        }
58

59
        while (buf + 1 <= end)
15,983,310✔
60
            *(buf++) = kos_rng_random(&rng);
15,979,601✔
61

62
        kos_unlock_mutex(ctx->inst->threads.ctx_mutex);
3,709✔
63
    }
64
#endif
65

66
    if (data) {
3,757✔
67
        data->ptr   = &data->buf[0];
3,709✔
68
        data->flags = 0;
3,709✔
69
        KOS_atomic_write_release_u32(data->capacity, capacity);
3,709✔
70
    }
71

72
    return data;
3,757✔
73
}
74

75
KOS_OBJ_ID KOS_new_buffer(KOS_CONTEXT ctx,
1,888✔
76
                          uint32_t    size)
77
{
78
    const uint32_t capacity = KOS_align_up(KOS_min(size, UINT32_MAX - KOS_BUFFER_CAPACITY_ALIGN), KOS_BUFFER_CAPACITY_ALIGN);
1,888✔
79
    KOS_LOCAL      obj;
80

81
    KOS_init_local_with(ctx, &obj, OBJID(BUFFER, (KOS_BUFFER *)
1,888✔
82
                kos_alloc_object(ctx,
83
                                 KOS_ALLOC_MOVABLE,
84
                                 OBJ_BUFFER,
85
                                 sizeof(KOS_BUFFER))));
86
    if ( ! IS_BAD_PTR(obj.o)) {
1,888✔
87

88
        OBJPTR(BUFFER, obj.o)->size  = size;
1,886✔
89
        OBJPTR(BUFFER, obj.o)->flags = 0;
1,886✔
90
        OBJPTR(BUFFER, obj.o)->data  = KOS_BADPTR;
1,886✔
91

92
        if (capacity) {
1,886✔
93

94
            KOS_BUFFER_STORAGE *data;
95

96
            data = alloc_buffer(ctx, capacity);
184✔
97

98
            if (data)
184✔
99
                KOS_atomic_write_release_ptr(OBJPTR(BUFFER, obj.o)->data,
184✔
100
                                             OBJID(BUFFER_STORAGE, data));
101
            else
UNCOV
102
                obj.o = KOS_BADPTR;
×
103
        }
104
    }
105

106
    return KOS_destroy_top_local(ctx, &obj);
1,888✔
107
}
108

109
KOS_OBJ_ID KOS_new_external_buffer(KOS_CONTEXT  ctx,
1✔
110
                                   void        *ptr,
111
                                   uint32_t     size,
112
                                   void        *priv,
113
                                   KOS_FINALIZE finalize)
114
{
115
    KOS_LOCAL obj;
116

117
    KOS_init_local(ctx, &obj);
1✔
118

119
    obj.o = OBJID(BUFFER, (KOS_BUFFER *)kos_alloc_object(ctx,
1✔
120
                                                         KOS_ALLOC_MOVABLE,
121
                                                         OBJ_BUFFER,
122
                                                         sizeof(KOS_BUFFER)));
123
    if ( ! IS_BAD_PTR(obj.o)) {
1✔
124

125
        KOS_BUFFER_EXTERNAL_STORAGE *data;
126

127
        OBJPTR(BUFFER, obj.o)->size  = size;
1✔
128
        OBJPTR(BUFFER, obj.o)->flags = KOS_EXTERNAL_STORAGE;
1✔
129
        OBJPTR(BUFFER, obj.o)->data  = KOS_BADPTR;
1✔
130

131
        data = (KOS_BUFFER_EXTERNAL_STORAGE *)alloc_buffer(ctx,
1✔
132
                (uint32_t)(sizeof(KOS_BUFFER_EXTERNAL_STORAGE) - (sizeof(KOS_BUFFER_STORAGE) - 1)));
133

134
        if (data) {
1✔
135
            KOS_atomic_write_release_ptr(OBJPTR(BUFFER, obj.o)->data,
1✔
136
                                         OBJID(BUFFER_STORAGE, (KOS_BUFFER_STORAGE *)data));
137
            data->ptr      = (uint8_t *)ptr;
1✔
138
            data->flags    = KOS_EXTERNAL_STORAGE;
1✔
139
            data->capacity = size;
1✔
140
            data->priv     = priv;
1✔
141
            data->finalize = finalize;
1✔
142
        }
143
        else
UNCOV
144
            obj.o = KOS_BADPTR;
×
145
    }
146

147
    return KOS_destroy_top_local(ctx, &obj);
1✔
148
}
149

150
static KOS_BUFFER_STORAGE *get_data(KOS_OBJ_ID obj_id)
11,746✔
151
{
152
    const KOS_OBJ_ID buf_obj = KOS_atomic_read_acquire_obj(OBJPTR(BUFFER, obj_id)->data);
11,746✔
153
    return IS_BAD_PTR(buf_obj) ? KOS_NULL : OBJPTR(BUFFER_STORAGE, buf_obj);
11,746✔
154
}
155

156
static KOS_OBJ_ID get_storage(KOS_OBJ_ID obj_id)
15,698✔
157
{
158
    const KOS_OBJ_ID storage_obj = KOS_atomic_read_acquire_obj(OBJPTR(BUFFER, obj_id)->data);
15,698✔
159
    return storage_obj;
15,698✔
160
}
161

162
int KOS_buffer_reserve(KOS_CONTEXT ctx,
3,606✔
163
                       KOS_OBJ_ID  obj_id,
164
                       uint32_t    new_capacity)
165
{
166
    KOS_LOCAL obj;
167
    KOS_LOCAL old_buf;
168
    int       error = KOS_ERROR_EXCEPTION;
3,606✔
169

170
    assert( ! IS_BAD_PTR(obj_id));
3,606✔
171

172
    KOS_init_local_with(ctx, &obj, obj_id);
3,606✔
173
    KOS_init_local(ctx, &old_buf);
3,606✔
174

175
    if (GET_OBJ_TYPE(obj.o) != OBJ_BUFFER)
3,606✔
176
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
177
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->flags) & KOS_READ_ONLY)
3,604✔
178
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
5✔
179
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->flags) & KOS_EXTERNAL_STORAGE)
3,599✔
UNCOV
180
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_external_storage));
×
181
    else {
182
        for (;;) {
761✔
183
            uint32_t capacity;
184

185
            old_buf.o = get_storage(obj.o);
4,360✔
186
            capacity  = IS_BAD_PTR(old_buf.o) ? 0
8,720✔
187
                      : KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER_STORAGE, old_buf.o)->capacity);
4,360✔
188

189
            new_capacity = KOS_align_up(KOS_min(new_capacity, UINT32_MAX - KOS_BUFFER_CAPACITY_ALIGN), KOS_BUFFER_CAPACITY_ALIGN);
4,360✔
190

191
            if (new_capacity > capacity) {
4,360✔
192

193
                uint32_t                  size;
194
                KOS_BUFFER_STORAGE *const buf = alloc_buffer(ctx, new_capacity);
3,572✔
195
                if ( ! buf)
3,572✔
196
                    break;
48✔
197

198
                size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->size);
3,524✔
199

200
                if (size > capacity)
3,524✔
201
                    continue;
761✔
202

203
                if (size)
2,763✔
204
                    memcpy(buf->ptr, OBJPTR(BUFFER_STORAGE, old_buf.o)->ptr, size);
1,163✔
205

206
                (void)KOS_atomic_cas_strong_ptr(OBJPTR(BUFFER, obj.o)->data,
2,763✔
207
                                                old_buf.o,
208
                                                OBJID(BUFFER_STORAGE, buf));
209
            }
210

211
            error = KOS_SUCCESS;
3,551✔
212
            break;
3,551✔
213
        }
214
    }
215

216
    KOS_destroy_top_locals(ctx, &old_buf, &obj);
3,606✔
217

218
    return error;
3,606✔
219
}
220

221
int KOS_buffer_resize(KOS_CONTEXT ctx,
2,114✔
222
                      KOS_OBJ_ID  obj_id,
223
                      uint32_t    size)
224
{
225
    int error = KOS_ERROR_EXCEPTION;
2,114✔
226

227
    assert( ! IS_BAD_PTR(obj_id));
2,114✔
228

229
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
2,114✔
230
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
231
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
2,112✔
232
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
5✔
233
    else {
234
        const uint32_t old_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->size);
2,107✔
235

236
        error = KOS_SUCCESS;
2,107✔
237

238
        if (size > old_size) {
2,107✔
239

240
            KOS_BUFFER_STORAGE *const data = get_data(obj_id);
1,710✔
241
            const uint32_t capacity = data ? KOS_atomic_read_relaxed_u32(data->capacity) : 0;
1,710✔
242

243
            if (size > capacity) {
1,710✔
244
                KOS_LOCAL      obj;
245
                const uint32_t new_capacity = (capacity > UINT32_MAX / 2 || size > capacity * 2)
1,620✔
246
                                              ? size : capacity * 2;
3,240✔
247

248
                KOS_init_local_with(ctx, &obj, obj_id);
1,620✔
249

250
                error = KOS_buffer_reserve(ctx, obj.o, new_capacity);
1,620✔
251

252
                obj_id = KOS_destroy_top_local(ctx, &obj);
1,620✔
253
            }
254
        }
255

256
        if ( ! error)
2,107✔
257
            KOS_atomic_swap_u32(OBJPTR(BUFFER, obj_id)->size, size);
2,059✔
258
    }
259

260
    return error;
2,114✔
261
}
262

263
uint8_t *KOS_buffer_data(KOS_CONTEXT ctx,
285✔
264
                         KOS_OBJ_ID  obj_id)
265
{
266
    uint8_t *ret = KOS_NULL;
285✔
267

268
    assert( ! IS_BAD_PTR(obj_id));
285✔
269

270
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
285✔
UNCOV
271
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
×
272
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
285✔
273
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
2✔
274
    else {
275

276
        KOS_OBJ_ID buf_id = get_storage(obj_id);
283✔
277

278
        if (IS_BAD_PTR(buf_id) || kos_is_heap_object(buf_id)) {
283✔
279

280
            KOS_LOCAL obj;
281
            int       error;
282

283
            KOS_init_local_with(ctx, &obj, obj_id);
182✔
284

285
            error = KOS_buffer_reserve(ctx, obj.o, KOS_MAX_HEAP_OBJ_SIZE * 2U);
182✔
286

287
            obj_id = KOS_destroy_top_local(ctx, &obj);
182✔
288

289
            if (error)
182✔
UNCOV
290
                goto cleanup;
×
291

292
            buf_id = get_storage(obj_id);
182✔
293
        }
294

295
        assert(kos_is_tracked_object(buf_id) && ! kos_is_heap_object(buf_id));
283✔
296

297
        ret = OBJPTR(BUFFER_STORAGE, buf_id)->ptr;
283✔
298
    }
299

300
cleanup:
285✔
301
    return ret;
285✔
302
}
303

304
uint8_t *KOS_buffer_data_volatile(KOS_CONTEXT ctx,
1,063,418✔
305
                                  KOS_OBJ_ID  obj_id)
306
{
307
    uint8_t *ret = KOS_NULL;
1,063,418✔
308

309
    assert( ! IS_BAD_PTR(obj_id));
1,063,418✔
310

311
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
1,063,418✔
UNCOV
312
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
×
313
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
1,063,418✔
314
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
2✔
315
    else {
316
        const KOS_OBJ_ID buf_obj = KOS_atomic_read_relaxed_obj(OBJPTR(BUFFER, obj_id)->data);
1,063,416✔
317

318
        if (IS_BAD_PTR(buf_obj))
1,063,416✔
UNCOV
319
            KOS_raise_exception(ctx, KOS_CONST_ID(str_err_empty));
×
320
        else {
321
            KOS_BUFFER_STORAGE *data = OBJPTR(BUFFER_STORAGE, buf_obj);
1,063,416✔
322

323
            ret = data->ptr;
1,063,416✔
324
        }
325
    }
326

327
    return ret;
1,063,418✔
328
}
329

330
uint8_t *KOS_buffer_make_room(KOS_CONTEXT ctx,
9,905✔
331
                              KOS_OBJ_ID  obj_id,
332
                              uint32_t    size_delta)
333
{
334
    uint8_t *ret = KOS_NULL;
9,905✔
335

336
    assert( ! IS_BAD_PTR(obj_id));
9,905✔
337

338
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
9,905✔
339
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
340
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
9,903✔
341
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
4✔
342
    else {
343
        for (;;) {
975✔
344
            uint32_t   new_size;
345
            KOS_OBJ_ID data_id;
346
            uint32_t   capacity;
347
            uint32_t   off_heap_size;
348

349
            const uint32_t old_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->size);
10,874✔
350

351
            if (size_delta > 0xFFFFFFFFU - old_size) {
10,874✔
352
                KOS_raise_exception(ctx, KOS_CONST_ID(str_err_make_room_size));
1✔
353
                break;
1✔
354
            }
355

356
            new_size = old_size + size_delta;
10,873✔
357
            data_id  = get_storage(obj_id);
10,873✔
358
            capacity = IS_BAD_PTR(data_id) ? 0 : KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER_STORAGE, data_id)->capacity);
10,873✔
359

360
            /* Ensure that the new buffer is allocated off heap */
361
            off_heap_size = KOS_max(new_size, KOS_MAX_HEAP_OBJ_SIZE * 2U);
10,873✔
362

363
            if (off_heap_size > capacity) {
10,873✔
364
                KOS_LOCAL      obj;
365
                const uint32_t new_capacity = (capacity > UINT32_MAX / 2 || new_size > capacity * 2)
1,789✔
366
                                              ? new_size : capacity * 2;
3,578✔
367
                int            error;
368

369
                KOS_init_local_with(ctx, &obj, obj_id);
1,789✔
370

371
                error = KOS_buffer_reserve(ctx, obj.o, new_capacity);
1,789✔
372

373
                obj_id = KOS_destroy_top_local(ctx, &obj);
1,789✔
374

375
                if (error)
1,789✔
UNCOV
376
                    break;
×
377
            }
378

379
            if (KOS_atomic_cas_strong_u32(OBJPTR(BUFFER, obj_id)->size, old_size, new_size)) {
10,873✔
380
                ret = KOS_buffer_data_volatile(ctx, obj_id);
9,898✔
381
                if (ret)
9,898✔
382
                    ret += old_size;
9,898✔
383
                break;
9,898✔
384
            }
385
        }
386
    }
387

388
    return ret;
9,905✔
389
}
390

391
int KOS_buffer_fill(KOS_CONTEXT ctx,
3,258✔
392
                    KOS_OBJ_ID  obj_id,
393
                    int64_t     begin,
394
                    int64_t     end,
395
                    uint8_t     value)
396
{
397
    int error = KOS_ERROR_EXCEPTION;
3,258✔
398

399
    assert( ! IS_BAD_PTR(obj_id));
3,258✔
400

401
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
3,258✔
402
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
403
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
3,256✔
404
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
2✔
405
    else {
406
        uint32_t size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->size);
3,254✔
407
        KOS_BUFFER_STORAGE *const data = get_data(obj_id);
3,254✔
408

409
        begin = KOS_fix_index(begin, size);
3,254✔
410
        end   = KOS_fix_index(end,   size);
3,254✔
411

412
        if (begin < end)
3,254✔
413
            memset(&data->ptr[begin], (int)value, (size_t)(end - begin));
3,252✔
414

415
        error = KOS_SUCCESS;
3,254✔
416
    }
417

418
    return error;
3,258✔
419
}
420

421
int KOS_buffer_copy(KOS_CONTEXT ctx,
3,359✔
422
                    KOS_OBJ_ID  destptr,
423
                    int64_t     dest_begin,
424
                    KOS_OBJ_ID  srcptr,
425
                    int64_t     src_begin,
426
                    int64_t     src_end)
427
{
428
    int error = KOS_ERROR_EXCEPTION;
3,359✔
429

430
    assert( ! IS_BAD_PTR(srcptr));
3,359✔
431
    assert( ! IS_BAD_PTR(destptr));
3,359✔
432

433
    if (GET_OBJ_TYPE(destptr) != OBJ_BUFFER ||
3,359✔
434
        GET_OBJ_TYPE(srcptr)  != OBJ_BUFFER)
3,357✔
435

436
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
4✔
437
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, destptr)->flags) & KOS_READ_ONLY)
3,355✔
UNCOV
438
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
×
439
    else {
440
        uint32_t dest_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, destptr)->size);
3,355✔
441
        KOS_BUFFER_STORAGE *const dest_data = get_data(destptr);
3,355✔
442

443
        uint32_t src_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, srcptr)->size);
3,355✔
444
        KOS_BUFFER_STORAGE *const src_data = get_data(srcptr);
3,355✔
445

446
        dest_begin = KOS_fix_index(dest_begin, dest_size);
3,355✔
447
        src_begin  = KOS_fix_index(src_begin, src_size);
3,355✔
448
        src_end    = KOS_fix_index(src_end,   src_size);
3,355✔
449

450
        if (src_begin < src_end && dest_begin < dest_size) {
3,355✔
451
            const size_t size = (size_t)KOS_min(src_end - src_begin, dest_size - dest_begin);
3,354✔
452
            uint8_t     *dest = &dest_data->ptr[dest_begin];
3,354✔
453
            uint8_t     *src  = &src_data->ptr[src_begin];
3,354✔
454

455
            if (src >= dest + size || src + size <= dest)
3,354✔
456
                memcpy(dest, src, size);
3,351✔
457
            else
458
                memmove(dest, src, size);
3✔
459
        }
460

461
        error = KOS_SUCCESS;
3,355✔
462
    }
463

464
    return error;
3,359✔
465
}
466

467
KOS_OBJ_ID KOS_buffer_slice(KOS_CONTEXT ctx,
41✔
468
                            KOS_OBJ_ID  obj_id,
469
                            int64_t     begin,
470
                            int64_t     end)
471
{
472
    KOS_LOCAL  obj;
473
    KOS_OBJ_ID ret = KOS_BADPTR;
41✔
474

475
    assert( ! IS_BAD_PTR(obj_id));
41✔
476

477
    KOS_init_local_with(ctx, &obj, obj_id);
41✔
478

479
    if (GET_OBJ_TYPE(obj.o) != OBJ_BUFFER)
41✔
480
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
481
    else {
482
        const uint32_t src_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->size);
39✔
483

484
        if (src_size) {
39✔
485

486
            uint32_t new_size;
487
            int64_t  new_size_64;
488

489
            begin = KOS_fix_index(begin, src_size);
38✔
490
            end   = KOS_fix_index(end,   src_size);
38✔
491

492
            if (end < begin)
38✔
493
                end = begin;
1✔
494

495
            new_size_64 = end - begin;
38✔
496
            assert(new_size_64 <= 0xFFFFFFFF);
38✔
497
            new_size = (uint32_t)new_size_64;
38✔
498

499
            ret = KOS_new_buffer(ctx, new_size);
38✔
500

501
            if (new_size && ! IS_BAD_PTR(ret)) {
38✔
502
                KOS_BUFFER_STORAGE *const dst_data = get_data(ret);
36✔
503
                memcpy(dst_data->ptr, &get_data(obj.o)->ptr[begin], new_size);
36✔
504
            }
505
        }
506
        else
507
            ret = KOS_new_buffer(ctx, 0);
1✔
508
    }
509

510
    KOS_destroy_top_local(ctx, &obj);
41✔
511

512
    return ret;
41✔
513
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc