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

kos-lang / kos / 6289842220

24 Sep 2023 11:47AM UTC coverage: 95.582% (-0.004%) from 95.586%
6289842220

push

github

Chris Dragan
net: add type cast to silence Coverity

Coverity incorrectly recognizes buffer being passed, which is done
with a union and without any type cast.  Add the type cast on the
pointer to the entire union just to avoid this false positive.

CID 1568325

24079 of 25192 relevant lines covered (95.58%)

1061624.01 hits per line

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

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

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

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

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

22
static KOS_BUFFER_STORAGE *alloc_buffer(KOS_CONTEXT ctx, unsigned capacity)
2,652✔
23
{
24
    KOS_BUFFER_STORAGE *const data = (KOS_BUFFER_STORAGE *)
25
            kos_alloc_object(ctx,
2,652✔
26
                             KOS_ALLOC_MOVABLE,
27
                             OBJ_BUFFER_STORAGE,
28
                             KOS_buffer_alloc_size(capacity));
29

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

42
        assert(kos_get_object_type(data->header) == OBJ_BUFFER_STORAGE);
2,604✔
43

44
        if ( ! init) {
2,604✔
45
            kos_rng_init(&rng);
234✔
46
            init = 1;
234✔
47
        }
48

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

53
        while (((intptr_t)buf & 7) && buf < end) {
2,604✔
54
            *(uint8_t *)buf = (uint8_t)kos_rng_random(&rng);
×
55
            buf = (uint64_t *)((intptr_t)buf + 1);
×
56
        }
57

58
        while (buf + 1 <= end)
15,457,100✔
59
            *(buf++) = kos_rng_random(&rng);
15,454,500✔
60

61
        kos_unlock_mutex(ctx->inst->threads.ctx_mutex);
2,604✔
62
    }
63
#endif
64

65
    if (data) {
2,652✔
66
        data->ptr   = &data->buf[0];
2,604✔
67
        data->flags = 0;
2,604✔
68
        KOS_atomic_write_release_u32(data->capacity, capacity);
2,604✔
69
    }
70

71
    return data;
2,652✔
72
}
73

74
KOS_OBJ_ID KOS_new_buffer(KOS_CONTEXT ctx,
1,803✔
75
                          unsigned    size)
76
{
77
    const unsigned capacity = (size + (KOS_BUFFER_CAPACITY_ALIGN-1)) & ~(KOS_BUFFER_CAPACITY_ALIGN-1);
1,803✔
78
    KOS_LOCAL      obj;
79

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

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

91
        if (capacity) {
1,801✔
92

93
            KOS_BUFFER_STORAGE *data;
94

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

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

105
    return KOS_destroy_top_local(ctx, &obj);
1,803✔
106
}
107

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

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

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

124
        KOS_BUFFER_EXTERNAL_STORAGE *data;
125

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

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

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

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

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

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

161
int KOS_buffer_reserve(KOS_CONTEXT ctx,
2,476✔
162
                       KOS_OBJ_ID  obj_id,
163
                       unsigned    new_capacity)
164
{
165
    KOS_LOCAL obj;
166
    KOS_LOCAL old_buf;
167
    int       error = KOS_ERROR_EXCEPTION;
2,476✔
168

169
    assert( ! IS_BAD_PTR(obj_id));
2,476✔
170

171
    KOS_init_local_with(ctx, &obj, obj_id);
2,476✔
172
    KOS_init_local(ctx, &old_buf);
2,476✔
173

174
    new_capacity = (new_capacity + (KOS_BUFFER_CAPACITY_ALIGN-1)) & ~(KOS_BUFFER_CAPACITY_ALIGN-1);
2,476✔
175

176
    if (GET_OBJ_TYPE(obj.o) != OBJ_BUFFER)
2,476✔
177
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
178
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->flags) & KOS_READ_ONLY)
2,474✔
179
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
5✔
180
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->flags) & KOS_EXTERNAL_STORAGE)
2,469✔
181
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_external_storage));
×
182
    else {
183
        for (;;) {
85✔
184
            uint32_t capacity;
185

186
            old_buf.o = get_storage(obj.o);
2,554✔
187
            capacity  = IS_BAD_PTR(old_buf.o) ? 0
5,108✔
188
                      : KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER_STORAGE, old_buf.o)->capacity);
2,554✔
189

190
            if (new_capacity > capacity) {
2,554✔
191

192
                uint32_t                  size;
193
                KOS_BUFFER_STORAGE *const buf = alloc_buffer(ctx, new_capacity);
2,467✔
194
                if ( ! buf)
2,467✔
195
                    break;
48✔
196

197
                size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->size);
2,419✔
198

199
                if (size > capacity)
2,419✔
200
                    continue;
85✔
201

202
                if (size)
2,334✔
203
                    memcpy(buf->ptr, OBJPTR(BUFFER_STORAGE, old_buf.o)->ptr, size);
819✔
204

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

210
            error = KOS_SUCCESS;
2,421✔
211
            break;
2,421✔
212
        }
213
    }
214

215
    KOS_destroy_top_locals(ctx, &old_buf, &obj);
2,476✔
216

217
    return error;
2,476✔
218
}
219

220
int KOS_buffer_resize(KOS_CONTEXT ctx,
1,856✔
221
                      KOS_OBJ_ID  obj_id,
222
                      unsigned    size)
223
{
224
    int error = KOS_ERROR_EXCEPTION;
1,856✔
225

226
    assert( ! IS_BAD_PTR(obj_id));
1,856✔
227

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

235
        error = KOS_SUCCESS;
1,849✔
236

237
        if (size > old_size) {
1,849✔
238

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

242
            if (size > capacity) {
1,622✔
243
                KOS_LOCAL      obj;
244
                const uint32_t new_capacity = size > capacity * 2 ? size : capacity * 2;
1,535✔
245

246
                KOS_init_local_with(ctx, &obj, obj_id);
1,535✔
247

248
                error = KOS_buffer_reserve(ctx, obj.o, new_capacity);
1,535✔
249

250
                obj_id = KOS_destroy_top_local(ctx, &obj);
1,535✔
251
            }
252
        }
253

254
        if ( ! error)
1,849✔
255
            KOS_atomic_swap_u32(OBJPTR(BUFFER, obj_id)->size, size);
1,801✔
256
    }
257

258
    return error;
1,856✔
259
}
260

261
uint8_t *KOS_buffer_data(KOS_CONTEXT ctx,
119✔
262
                         KOS_OBJ_ID  obj_id)
263
{
264
    uint8_t *ret = KOS_NULL;
119✔
265

266
    assert( ! IS_BAD_PTR(obj_id));
119✔
267

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

274
        KOS_OBJ_ID buf_id = get_storage(obj_id);
117✔
275

276
        if (IS_BAD_PTR(buf_id) || kos_is_heap_object(buf_id)) {
117✔
277

278
            KOS_LOCAL obj;
279
            int       error;
280

281
            KOS_init_local_with(ctx, &obj, obj_id);
20✔
282

283
            error = KOS_buffer_reserve(ctx, obj.o, KOS_MAX_HEAP_OBJ_SIZE * 2U);
20✔
284

285
            obj_id = KOS_destroy_top_local(ctx, &obj);
20✔
286

287
            if (error)
20✔
288
                goto cleanup;
×
289

290
            buf_id = get_storage(obj_id);
20✔
291
        }
292

293
        assert(kos_is_tracked_object(buf_id) && ! kos_is_heap_object(buf_id));
117✔
294

295
        ret = OBJPTR(BUFFER_STORAGE, buf_id)->ptr;
117✔
296
    }
297

298
cleanup:
119✔
299
    return ret;
119✔
300
}
301

302
uint8_t *KOS_buffer_data_volatile(KOS_CONTEXT ctx,
10,046✔
303
                                  KOS_OBJ_ID  obj_id)
304
{
305
    uint8_t *ret = KOS_NULL;
10,046✔
306

307
    assert( ! IS_BAD_PTR(obj_id));
10,046✔
308

309
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
10,046✔
310
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
×
311
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
10,046✔
312
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
2✔
313
    else {
314
        const KOS_OBJ_ID buf_obj = KOS_atomic_read_relaxed_obj(OBJPTR(BUFFER, obj_id)->data);
10,044✔
315

316
        if (IS_BAD_PTR(buf_obj))
10,044✔
317
            KOS_raise_exception(ctx, KOS_CONST_ID(str_err_empty));
×
318
        else {
319
            KOS_BUFFER_STORAGE *data = OBJPTR(BUFFER_STORAGE, buf_obj);
10,044✔
320

321
            ret = data->ptr;
10,044✔
322
        }
323
    }
324

325
    return ret;
10,046✔
326
}
327

328
uint8_t *KOS_buffer_make_room(KOS_CONTEXT ctx,
5,031✔
329
                              KOS_OBJ_ID  obj_id,
330
                              unsigned    size_delta)
331
{
332
    uint8_t *ret = KOS_NULL;
5,031✔
333

334
    assert( ! IS_BAD_PTR(obj_id));
5,031✔
335

336
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
5,031✔
337
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
338
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
5,029✔
339
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
4✔
340
    else {
341
        for (;;) {
90✔
342
            const uint32_t   old_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->size);
5,115✔
343
            const uint32_t   new_size = old_size + size_delta;
5,115✔
344
            const KOS_OBJ_ID data_id  = get_storage(obj_id);
5,115✔
345
            const uint32_t   capacity = IS_BAD_PTR(data_id) ? 0 :
5,112✔
346
                    KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER_STORAGE, data_id)->capacity);
5,074✔
347

348
            /* Ensure that the new buffer is allocated off heap */
349
            const uint32_t off_heap_size = KOS_max(new_size, KOS_MAX_HEAP_OBJ_SIZE * 2U);
5,112✔
350

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

356
            if (off_heap_size > capacity) {
5,111✔
357
                KOS_LOCAL      obj;
358
                const uint32_t new_capacity = new_size > capacity * 2 ? new_size : capacity * 2;
906✔
359
                int            error;
360

361
                KOS_init_local_with(ctx, &obj, obj_id);
906✔
362

363
                error = KOS_buffer_reserve(ctx, obj.o, new_capacity);
906✔
364

365
                obj_id = KOS_destroy_top_local(ctx, &obj);
906✔
366

367
                if (error)
906✔
368
                    break;
×
369
            }
370

371
            if (KOS_atomic_cas_strong_u32(OBJPTR(BUFFER, obj_id)->size, old_size, new_size)) {
5,111✔
372
                ret = KOS_buffer_data_volatile(ctx, obj_id);
5,023✔
373
                if (ret)
5,024✔
374
                    ret += old_size;
5,024✔
375
                break;
5,024✔
376
            }
377
        }
378
    }
379

380
    return ret;
5,031✔
381
}
382

383
int KOS_buffer_fill(KOS_CONTEXT ctx,
1,608✔
384
                    KOS_OBJ_ID  obj_id,
385
                    int64_t     begin,
386
                    int64_t     end,
387
                    uint8_t     value)
388
{
389
    int error = KOS_ERROR_EXCEPTION;
1,608✔
390

391
    assert( ! IS_BAD_PTR(obj_id));
1,608✔
392

393
    if (GET_OBJ_TYPE(obj_id) != OBJ_BUFFER)
1,608✔
394
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
395
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->flags) & KOS_READ_ONLY)
1,606✔
396
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
2✔
397
    else {
398
        uint32_t size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj_id)->size);
1,604✔
399
        KOS_BUFFER_STORAGE *const data = get_data(obj_id);
1,604✔
400

401
        begin = KOS_fix_index(begin, size);
1,604✔
402
        end   = KOS_fix_index(end,   size);
1,604✔
403

404
        if (begin < end)
1,604✔
405
            memset(&data->ptr[begin], (int)value, (size_t)(end - begin));
1,602✔
406

407
        error = KOS_SUCCESS;
1,604✔
408
    }
409

410
    return error;
1,608✔
411
}
412

413
int KOS_buffer_copy(KOS_CONTEXT ctx,
1,691✔
414
                    KOS_OBJ_ID  destptr,
415
                    int64_t     dest_begin,
416
                    KOS_OBJ_ID  srcptr,
417
                    int64_t     src_begin,
418
                    int64_t     src_end)
419
{
420
    int error = KOS_ERROR_EXCEPTION;
1,691✔
421

422
    assert( ! IS_BAD_PTR(srcptr));
1,691✔
423
    assert( ! IS_BAD_PTR(destptr));
1,691✔
424

425
    if (GET_OBJ_TYPE(destptr) != OBJ_BUFFER ||
1,691✔
426
        GET_OBJ_TYPE(srcptr)  != OBJ_BUFFER)
1,689✔
427

428
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
4✔
429
    else if (KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, destptr)->flags) & KOS_READ_ONLY)
1,687✔
430
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_read_only));
×
431
    else {
432
        uint32_t dest_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, destptr)->size);
1,687✔
433
        KOS_BUFFER_STORAGE *const dest_data = get_data(destptr);
1,687✔
434

435
        uint32_t src_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, srcptr)->size);
1,687✔
436
        KOS_BUFFER_STORAGE *const src_data = get_data(srcptr);
1,687✔
437

438
        dest_begin = KOS_fix_index(dest_begin, dest_size);
1,687✔
439
        src_begin  = KOS_fix_index(src_begin, src_size);
1,687✔
440
        src_end    = KOS_fix_index(src_end,   src_size);
1,687✔
441

442
        if (src_begin < src_end && dest_begin < dest_size) {
1,687✔
443
            const size_t size = (size_t)KOS_min(src_end - src_begin, dest_size - dest_begin);
1,686✔
444
            uint8_t     *dest = &dest_data->ptr[dest_begin];
1,686✔
445
            uint8_t     *src  = &src_data->ptr[src_begin];
1,686✔
446

447
            if (src >= dest + size || src + size <= dest)
1,686✔
448
                memcpy(dest, src, size);
1,683✔
449
            else
450
                memmove(dest, src, size);
3✔
451
        }
452

453
        error = KOS_SUCCESS;
1,687✔
454
    }
455

456
    return error;
1,691✔
457
}
458

459
KOS_OBJ_ID KOS_buffer_slice(KOS_CONTEXT ctx,
41✔
460
                            KOS_OBJ_ID  obj_id,
461
                            int64_t     begin,
462
                            int64_t     end)
463
{
464
    KOS_LOCAL  obj;
465
    KOS_OBJ_ID ret = KOS_BADPTR;
41✔
466

467
    assert( ! IS_BAD_PTR(obj_id));
41✔
468

469
    KOS_init_local_with(ctx, &obj, obj_id);
41✔
470

471
    if (GET_OBJ_TYPE(obj.o) != OBJ_BUFFER)
41✔
472
        KOS_raise_exception(ctx, KOS_CONST_ID(str_err_not_buffer));
2✔
473
    else {
474
        const uint32_t src_size = KOS_atomic_read_relaxed_u32(OBJPTR(BUFFER, obj.o)->size);
39✔
475

476
        if (src_size) {
39✔
477

478
            uint32_t new_size;
479
            int64_t  new_size_64;
480

481
            begin = KOS_fix_index(begin, src_size);
38✔
482
            end   = KOS_fix_index(end,   src_size);
38✔
483

484
            if (end < begin)
38✔
485
                end = begin;
1✔
486

487
            new_size_64 = end - begin;
38✔
488
            assert(new_size_64 <= 0xFFFFFFFF);
38✔
489
            new_size = (uint32_t)new_size_64;
38✔
490

491
            ret = KOS_new_buffer(ctx, new_size);
38✔
492

493
            if (new_size && ! IS_BAD_PTR(ret)) {
38✔
494
                KOS_BUFFER_STORAGE *const dst_data = get_data(ret);
36✔
495
                memcpy(dst_data->ptr, &get_data(obj.o)->ptr[begin], new_size);
36✔
496
            }
497
        }
498
        else
499
            ret = KOS_new_buffer(ctx, 0);
1✔
500
    }
501

502
    KOS_destroy_top_local(ctx, &obj);
41✔
503

504
    return ret;
41✔
505
}
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