MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

TypedArray, DataView

+970 -2
+4 -1
.gitignore
··· 9 9 /build 10 10 /subprojects/*/ 11 11 /subprojects/.wraplock 12 - !/subprojects/packagefiles 12 + !/subprojects/packagefiles 13 + 14 + *.todo 15 + todo.txt
+44
include/modules/buffer.h
··· 1 + #ifndef BUFFER_H 2 + #define BUFFER_H 3 + 4 + #include <stdint.h> 5 + #include <stddef.h> 6 + 7 + void init_buffer_module(void); 8 + 9 + typedef struct { 10 + uint8_t *data; 11 + size_t length; 12 + size_t capacity; 13 + int ref_count; 14 + } ArrayBufferData; 15 + 16 + typedef enum { 17 + TYPED_ARRAY_INT8, 18 + TYPED_ARRAY_UINT8, 19 + TYPED_ARRAY_UINT8_CLAMPED, 20 + TYPED_ARRAY_INT16, 21 + TYPED_ARRAY_UINT16, 22 + TYPED_ARRAY_INT32, 23 + TYPED_ARRAY_UINT32, 24 + TYPED_ARRAY_FLOAT32, 25 + TYPED_ARRAY_FLOAT64, 26 + TYPED_ARRAY_BIGINT64, 27 + TYPED_ARRAY_BIGUINT64 28 + } TypedArrayType; 29 + 30 + typedef struct { 31 + ArrayBufferData *buffer; 32 + TypedArrayType type; 33 + size_t byte_offset; 34 + size_t byte_length; 35 + size_t length; 36 + } TypedArrayData; 37 + 38 + typedef struct { 39 + ArrayBufferData *buffer; 40 + size_t byte_offset; 41 + size_t byte_length; 42 + } DataViewData; 43 + 44 + #endif
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.0.7.33') 77 + version_conf.set('ANT_VERSION', '0.0.7.34') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+1
src/ant.c
··· 4194 4194 case TOK_TRUE: return js_mktrue(); 4195 4195 case TOK_FALSE: return js_mkfalse(); 4196 4196 case TOK_THIS: return js->this_val; 4197 + case TOK_FROM: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 4197 4198 case TOK_VOID: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 4198 4199 case TOK_DELETE: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 4199 4200 case TOK_IMPORT: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen);
+2
src/main.c
··· 11 11 #include "repl.h" 12 12 13 13 #include "modules/builtin.h" 14 + #include "modules/buffer.h" 14 15 #include "modules/io.h" 15 16 #include "modules/fs.h" 16 17 #include "modules/crypto.h" ··· 154 155 ant_runtime_init(js); 155 156 156 157 init_builtin_module(); 158 + init_buffer_module(); 157 159 init_crypto_module(); 158 160 init_fetch_module(); 159 161 init_console_module();
+721
src/modules/buffer.c
··· 1 + #include <stdlib.h> 2 + #include <stdio.h> 3 + #include <string.h> 4 + #include <ctype.h> 5 + 6 + #include "ant.h" 7 + #include "runtime.h" 8 + #include "modules/buffer.h" 9 + 10 + static jsval_t js_arraybuffer_slice(struct js *js, jsval_t *args, int nargs); 11 + static jsval_t js_typedarray_slice(struct js *js, jsval_t *args, int nargs); 12 + static jsval_t js_typedarray_subarray(struct js *js, jsval_t *args, int nargs); 13 + static jsval_t js_dataview_getUint8(struct js *js, jsval_t *args, int nargs); 14 + static jsval_t js_dataview_setUint8(struct js *js, jsval_t *args, int nargs); 15 + static jsval_t js_dataview_getInt16(struct js *js, jsval_t *args, int nargs); 16 + static jsval_t js_dataview_getInt32(struct js *js, jsval_t *args, int nargs); 17 + static jsval_t js_dataview_getFloat32(struct js *js, jsval_t *args, int nargs); 18 + static jsval_t js_buffer_toString(struct js *js, jsval_t *args, int nargs); 19 + static jsval_t js_buffer_toBase64(struct js *js, jsval_t *args, int nargs); 20 + static jsval_t js_buffer_write(struct js *js, jsval_t *args, int nargs); 21 + 22 + static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 23 + 24 + static const unsigned char base64_decode_table[256] = { 25 + ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7, 26 + ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15, 27 + ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, 28 + ['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31, 29 + ['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, 30 + ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47, 31 + ['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55, 32 + ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63, 33 + }; 34 + 35 + static char *base64_encode(const uint8_t *data, size_t len, size_t *out_len) { 36 + size_t encoded_len = 4 * ((len + 2) / 3); 37 + char *result = malloc(encoded_len + 1); 38 + if (!result) return NULL; 39 + 40 + size_t j = 0; 41 + for (size_t i = 0; i < len; i += 3) { 42 + uint32_t octet_a = i < len ? data[i] : 0; 43 + uint32_t octet_b = i + 1 < len ? data[i + 1] : 0; 44 + uint32_t octet_c = i + 2 < len ? data[i + 2] : 0; 45 + uint32_t triple = (octet_a << 16) + (octet_b << 8) + octet_c; 46 + 47 + result[j++] = base64_chars[(triple >> 18) & 0x3F]; 48 + result[j++] = base64_chars[(triple >> 12) & 0x3F]; 49 + result[j++] = (i + 1 < len) ? base64_chars[(triple >> 6) & 0x3F] : '='; 50 + result[j++] = (i + 2 < len) ? base64_chars[triple & 0x3F] : '='; 51 + } 52 + 53 + result[j] = '\0'; 54 + *out_len = j; 55 + return result; 56 + } 57 + 58 + static uint8_t *base64_decode(const char *data, size_t len, size_t *out_len) { 59 + if (len % 4 != 0) return NULL; 60 + 61 + size_t decoded_len = len / 4 * 3; 62 + if (len > 0 && data[len - 1] == '=') decoded_len--; 63 + if (len > 1 && data[len - 2] == '=') decoded_len--; 64 + 65 + uint8_t *result = malloc(decoded_len); 66 + if (!result) return NULL; 67 + 68 + size_t j = 0; 69 + for (size_t i = 0; i < len; i += 4) { 70 + uint32_t sextet_a = base64_decode_table[(unsigned char)data[i]]; 71 + uint32_t sextet_b = base64_decode_table[(unsigned char)data[i + 1]]; 72 + uint32_t sextet_c = data[i + 2] == '=' ? 0 : base64_decode_table[(unsigned char)data[i + 2]]; 73 + uint32_t sextet_d = data[i + 3] == '=' ? 0 : base64_decode_table[(unsigned char)data[i + 3]]; 74 + uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d; 75 + 76 + if (j < decoded_len) result[j++] = (triple >> 16) & 0xFF; 77 + if (j < decoded_len) result[j++] = (triple >> 8) & 0xFF; 78 + if (j < decoded_len) result[j++] = triple & 0xFF; 79 + } 80 + 81 + *out_len = decoded_len; 82 + return result; 83 + } 84 + 85 + static ArrayBufferData *create_array_buffer_data(size_t length) { 86 + ArrayBufferData *data = malloc(sizeof(ArrayBufferData)); 87 + if (!data) return NULL; 88 + 89 + data->data = calloc(length, 1); 90 + if (!data->data && length > 0) { 91 + free(data); 92 + return NULL; 93 + } 94 + 95 + data->length = length; 96 + data->capacity = length; 97 + data->ref_count = 1; 98 + return data; 99 + } 100 + 101 + static void free_array_buffer_data(ArrayBufferData *data) { 102 + if (!data) return; 103 + data->ref_count--; 104 + if (data->ref_count <= 0) { 105 + free(data->data); 106 + free(data); 107 + } 108 + } 109 + 110 + static size_t get_element_size(TypedArrayType type) { 111 + switch (type) { 112 + case TYPED_ARRAY_INT8: 113 + case TYPED_ARRAY_UINT8: 114 + case TYPED_ARRAY_UINT8_CLAMPED: 115 + return 1; 116 + case TYPED_ARRAY_INT16: 117 + case TYPED_ARRAY_UINT16: 118 + return 2; 119 + case TYPED_ARRAY_INT32: 120 + case TYPED_ARRAY_UINT32: 121 + case TYPED_ARRAY_FLOAT32: 122 + return 4; 123 + case TYPED_ARRAY_FLOAT64: 124 + case TYPED_ARRAY_BIGINT64: 125 + case TYPED_ARRAY_BIGUINT64: 126 + return 8; 127 + default: 128 + return 1; 129 + } 130 + } 131 + 132 + // ArrayBuffer constructor 133 + static jsval_t js_arraybuffer_constructor(struct js *js, jsval_t *args, int nargs) { 134 + size_t length = 0; 135 + if (nargs > 0 && js_type(args[0]) == JS_NUM) { 136 + length = (size_t)js_getnum(args[0]); 137 + } 138 + 139 + ArrayBufferData *data = create_array_buffer_data(length); 140 + if (!data) { 141 + return js_mkerr(js, "Failed to allocate ArrayBuffer"); 142 + } 143 + 144 + jsval_t obj = js_mkobj(js); 145 + js_set(js, obj, "_arraybuffer_data", js_mknum((double)(uintptr_t)data)); 146 + js_set(js, obj, "byteLength", js_mknum((double)length)); 147 + js_set(js, obj, "slice", js_mkfun(js_arraybuffer_slice)); 148 + 149 + return obj; 150 + } 151 + 152 + // ArrayBuffer.prototype.slice(begin, end) 153 + static jsval_t js_arraybuffer_slice(struct js *js, jsval_t *args, int nargs) { 154 + jsval_t this_val = js_getthis(js); 155 + jsval_t data_val = js_get(js, this_val, "_arraybuffer_data"); 156 + 157 + if (js_type(data_val) != JS_NUM) { 158 + return js_mkerr(js, "Not an ArrayBuffer"); 159 + } 160 + 161 + ArrayBufferData *data = (ArrayBufferData *)(uintptr_t)js_getnum(data_val); 162 + if (!data) return js_mkerr(js, "Invalid ArrayBuffer"); 163 + 164 + int begin = 0, end = data->length; 165 + if (nargs > 0 && js_type(args[0]) == JS_NUM) begin = (int)js_getnum(args[0]); 166 + if (nargs > 1 && js_type(args[1]) == JS_NUM) end = (int)js_getnum(args[1]); 167 + 168 + if (begin < 0) begin = data->length + begin; 169 + if (end < 0) end = data->length + end; 170 + if (begin < 0) begin = 0; 171 + if (end < 0) end = 0; 172 + if (begin > (int)data->length) begin = data->length; 173 + if (end > (int)data->length) end = data->length; 174 + if (end < begin) end = begin; 175 + 176 + size_t new_length = end - begin; 177 + ArrayBufferData *new_data = create_array_buffer_data(new_length); 178 + if (!new_data) return js_mkerr(js, "Failed to allocate new ArrayBuffer"); 179 + 180 + memcpy(new_data->data, data->data + begin, new_length); 181 + 182 + jsval_t new_obj = js_mkobj(js); 183 + js_set(js, new_obj, "_arraybuffer_data", js_mknum((double)(uintptr_t)new_data)); 184 + js_set(js, new_obj, "byteLength", js_mknum((double)new_length)); 185 + js_set(js, new_obj, "slice", js_mkfun(js_arraybuffer_slice)); 186 + 187 + return new_obj; 188 + } 189 + 190 + static jsval_t create_typed_array(struct js *js, TypedArrayType type, ArrayBufferData *buffer, size_t byte_offset, size_t length, const char *type_name) { 191 + TypedArrayData *ta_data = malloc(sizeof(TypedArrayData)); 192 + if (!ta_data) return js_mkerr(js, "Failed to allocate TypedArray"); 193 + 194 + size_t element_size = get_element_size(type); 195 + ta_data->buffer = buffer; 196 + ta_data->type = type; 197 + ta_data->byte_offset = byte_offset; 198 + ta_data->byte_length = length * element_size; 199 + ta_data->length = length; 200 + buffer->ref_count++; 201 + 202 + jsval_t obj = js_mkobj(js); 203 + js_set(js, obj, "_typedarray_data", js_mknum((double)(uintptr_t)ta_data)); 204 + js_set(js, obj, "length", js_mknum((double)length)); 205 + js_set(js, obj, "byteLength", js_mknum((double)(length * element_size))); 206 + js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); 207 + js_set(js, obj, "BYTES_PER_ELEMENT", js_mknum((double)element_size)); 208 + js_set(js, obj, "slice", js_mkfun(js_typedarray_slice)); 209 + js_set(js, obj, "subarray", js_mkfun(js_typedarray_subarray)); 210 + 211 + return obj; 212 + } 213 + 214 + static jsval_t js_typedarray_constructor(struct js *js, jsval_t *args, int nargs, TypedArrayType type, const char *type_name) { 215 + if (nargs == 0) { 216 + ArrayBufferData *buffer = create_array_buffer_data(0); 217 + return create_typed_array(js, type, buffer, 0, 0, type_name); 218 + } 219 + 220 + if (js_type(args[0]) == JS_NUM) { 221 + size_t length = (size_t)js_getnum(args[0]); 222 + size_t element_size = get_element_size(type); 223 + ArrayBufferData *buffer = create_array_buffer_data(length * element_size); 224 + if (!buffer) return js_mkerr(js, "Failed to allocate buffer"); 225 + return create_typed_array(js, type, buffer, 0, length, type_name); 226 + } 227 + 228 + jsval_t buffer_data_val = js_get(js, args[0], "_arraybuffer_data"); 229 + if (js_type(buffer_data_val) == JS_NUM) { 230 + ArrayBufferData *buffer = (ArrayBufferData *)(uintptr_t)js_getnum(buffer_data_val); 231 + size_t byte_offset = 0; 232 + size_t length = buffer->length; 233 + 234 + if (nargs > 1 && js_type(args[1]) == JS_NUM) { 235 + byte_offset = (size_t)js_getnum(args[1]); 236 + } 237 + 238 + size_t element_size = get_element_size(type); 239 + if (nargs > 2 && js_type(args[2]) == JS_NUM) { 240 + length = (size_t)js_getnum(args[2]); 241 + } else { 242 + length = (buffer->length - byte_offset) / element_size; 243 + } 244 + 245 + return create_typed_array(js, type, buffer, byte_offset, length, type_name); 246 + } 247 + 248 + return js_mkerr(js, "Invalid TypedArray constructor arguments"); 249 + } 250 + 251 + // TypedArray.prototype.slice(begin, end) 252 + static jsval_t js_typedarray_slice(struct js *js, jsval_t *args, int nargs) { 253 + jsval_t this_val = js_getthis(js); 254 + jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 255 + 256 + if (js_type(ta_data_val) != JS_NUM) { 257 + return js_mkerr(js, "Not a TypedArray"); 258 + } 259 + 260 + TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 261 + if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 262 + 263 + int begin = 0, end = ta_data->length; 264 + if (nargs > 0 && js_type(args[0]) == JS_NUM) begin = (int)js_getnum(args[0]); 265 + if (nargs > 1 && js_type(args[1]) == JS_NUM) end = (int)js_getnum(args[1]); 266 + 267 + if (begin < 0) begin = ta_data->length + begin; 268 + if (end < 0) end = ta_data->length + end; 269 + if (begin < 0) begin = 0; 270 + if (end < 0) end = 0; 271 + if (begin > (int)ta_data->length) begin = ta_data->length; 272 + if (end > (int)ta_data->length) end = ta_data->length; 273 + if (end < begin) end = begin; 274 + 275 + size_t new_length = end - begin; 276 + size_t element_size = get_element_size(ta_data->type); 277 + ArrayBufferData *new_buffer = create_array_buffer_data(new_length * element_size); 278 + if (!new_buffer) return js_mkerr(js, "Failed to allocate new buffer"); 279 + 280 + memcpy( 281 + new_buffer->data, 282 + ta_data->buffer->data + ta_data->byte_offset + begin * element_size, 283 + new_length * element_size 284 + ); 285 + 286 + return create_typed_array(js, ta_data->type, new_buffer, 0, new_length, "TypedArray"); 287 + } 288 + 289 + // TypedArray.prototype.subarray(begin, end) 290 + static jsval_t js_typedarray_subarray(struct js *js, jsval_t *args, int nargs) { 291 + jsval_t this_val = js_getthis(js); 292 + jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 293 + 294 + if (js_type(ta_data_val) != JS_NUM) { 295 + return js_mkerr(js, "Not a TypedArray"); 296 + } 297 + 298 + TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 299 + if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 300 + 301 + int begin = 0, end = ta_data->length; 302 + if (nargs > 0 && js_type(args[0]) == JS_NUM) begin = (int)js_getnum(args[0]); 303 + if (nargs > 1 && js_type(args[1]) == JS_NUM) end = (int)js_getnum(args[1]); 304 + 305 + if (begin < 0) begin = ta_data->length + begin; 306 + if (end < 0) end = ta_data->length + end; 307 + if (begin < 0) begin = 0; 308 + if (end < 0) end = 0; 309 + if (begin > (int)ta_data->length) begin = ta_data->length; 310 + if (end > (int)ta_data->length) end = ta_data->length; 311 + if (end < begin) end = begin; 312 + 313 + size_t new_length = end - begin; 314 + size_t element_size = get_element_size(ta_data->type); 315 + size_t new_offset = ta_data->byte_offset + begin * element_size; 316 + 317 + return create_typed_array(js, ta_data->type, ta_data->buffer, new_offset, new_length, "TypedArray"); 318 + } 319 + 320 + #define DEFINE_TYPEDARRAY_CONSTRUCTOR(name, type) \ 321 + static jsval_t js_##name##_constructor(struct js *js, jsval_t *args, int nargs) { \ 322 + return js_typedarray_constructor(js, args, nargs, type, #name); \ 323 + } 324 + 325 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Int8Array, TYPED_ARRAY_INT8) 326 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Uint8Array, TYPED_ARRAY_UINT8) 327 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Uint8ClampedArray, TYPED_ARRAY_UINT8_CLAMPED) 328 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Int16Array, TYPED_ARRAY_INT16) 329 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Uint16Array, TYPED_ARRAY_UINT16) 330 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Int32Array, TYPED_ARRAY_INT32) 331 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Uint32Array, TYPED_ARRAY_UINT32) 332 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Float32Array, TYPED_ARRAY_FLOAT32) 333 + DEFINE_TYPEDARRAY_CONSTRUCTOR(Float64Array, TYPED_ARRAY_FLOAT64) 334 + DEFINE_TYPEDARRAY_CONSTRUCTOR(BigInt64Array, TYPED_ARRAY_BIGINT64) 335 + DEFINE_TYPEDARRAY_CONSTRUCTOR(BigUint64Array, TYPED_ARRAY_BIGUINT64) 336 + 337 + static jsval_t js_dataview_constructor(struct js *js, jsval_t *args, int nargs) { 338 + if (nargs < 1) { 339 + return js_mkerr(js, "DataView requires an ArrayBuffer"); 340 + } 341 + 342 + jsval_t buffer_data_val = js_get(js, args[0], "_arraybuffer_data"); 343 + if (js_type(buffer_data_val) != JS_NUM) { 344 + return js_mkerr(js, "First argument must be an ArrayBuffer"); 345 + } 346 + 347 + ArrayBufferData *buffer = (ArrayBufferData *)(uintptr_t)js_getnum(buffer_data_val); 348 + size_t byte_offset = 0; 349 + size_t byte_length = buffer->length; 350 + 351 + if (nargs > 1 && js_type(args[1]) == JS_NUM) { 352 + byte_offset = (size_t)js_getnum(args[1]); 353 + } 354 + 355 + if (nargs > 2 && js_type(args[2]) == JS_NUM) { 356 + byte_length = (size_t)js_getnum(args[2]); 357 + } else { 358 + byte_length = buffer->length - byte_offset; 359 + } 360 + 361 + DataViewData *dv_data = malloc(sizeof(DataViewData)); 362 + if (!dv_data) return js_mkerr(js, "Failed to allocate DataView"); 363 + 364 + dv_data->buffer = buffer; 365 + dv_data->byte_offset = byte_offset; 366 + dv_data->byte_length = byte_length; 367 + buffer->ref_count++; 368 + 369 + jsval_t obj = js_mkobj(js); 370 + js_set(js, obj, "_dataview_data", js_mknum((double)(uintptr_t)dv_data)); 371 + js_set(js, obj, "byteLength", js_mknum((double)byte_length)); 372 + js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); 373 + js_set(js, obj, "getUint8", js_mkfun(js_dataview_getUint8)); 374 + js_set(js, obj, "setUint8", js_mkfun(js_dataview_setUint8)); 375 + js_set(js, obj, "getInt16", js_mkfun(js_dataview_getInt16)); 376 + js_set(js, obj, "getInt32", js_mkfun(js_dataview_getInt32)); 377 + js_set(js, obj, "getFloat32", js_mkfun(js_dataview_getFloat32)); 378 + 379 + return obj; 380 + } 381 + 382 + // DataView.prototype.getUint8(byteOffset) 383 + static jsval_t js_dataview_getUint8(struct js *js, jsval_t *args, int nargs) { 384 + if (nargs < 1) return js_mkerr(js, "getUint8 requires byteOffset"); 385 + 386 + jsval_t this_val = js_getthis(js); 387 + jsval_t dv_data_val = js_get(js, this_val, "_dataview_data"); 388 + 389 + if (js_type(dv_data_val) != JS_NUM) { 390 + return js_mkerr(js, "Not a DataView"); 391 + } 392 + 393 + DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); 394 + size_t offset = (size_t)js_getnum(args[0]); 395 + 396 + if (offset >= dv->byte_length) { 397 + return js_mkerr(js, "Offset out of bounds"); 398 + } 399 + 400 + uint8_t value = dv->buffer->data[dv->byte_offset + offset]; 401 + return js_mknum((double)value); 402 + } 403 + 404 + // DataView.prototype.setUint8(byteOffset, value) 405 + static jsval_t js_dataview_setUint8(struct js *js, jsval_t *args, int nargs) { 406 + if (nargs < 2) return js_mkerr(js, "setUint8 requires byteOffset and value"); 407 + 408 + jsval_t this_val = js_getthis(js); 409 + jsval_t dv_data_val = js_get(js, this_val, "_dataview_data"); 410 + 411 + if (js_type(dv_data_val) != JS_NUM) { 412 + return js_mkerr(js, "Not a DataView"); 413 + } 414 + 415 + DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); 416 + size_t offset = (size_t)js_getnum(args[0]); 417 + uint8_t value = (uint8_t)js_getnum(args[1]); 418 + 419 + if (offset >= dv->byte_length) { 420 + return js_mkerr(js, "Offset out of bounds"); 421 + } 422 + 423 + dv->buffer->data[dv->byte_offset + offset] = value; 424 + return js_mkundef(); 425 + } 426 + 427 + // DataView.prototype.getInt16(byteOffset, littleEndian) 428 + static jsval_t js_dataview_getInt16(struct js *js, jsval_t *args, int nargs) { 429 + if (nargs < 1) return js_mkerr(js, "getInt16 requires byteOffset"); 430 + 431 + jsval_t this_val = js_getthis(js); 432 + jsval_t dv_data_val = js_get(js, this_val, "_dataview_data"); 433 + 434 + if (js_type(dv_data_val) != JS_NUM) { 435 + return js_mkerr(js, "Not a DataView"); 436 + } 437 + 438 + DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); 439 + size_t offset = (size_t)js_getnum(args[0]); 440 + bool little_endian = (nargs > 1 && js_truthy(js, args[1])); 441 + 442 + if (offset + 2 > dv->byte_length) { 443 + return js_mkerr(js, "Offset out of bounds"); 444 + } 445 + 446 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 447 + int16_t value; 448 + 449 + if (little_endian) { 450 + value = (int16_t)(ptr[0] | (ptr[1] << 8)); 451 + } else { 452 + value = (int16_t)((ptr[0] << 8) | ptr[1]); 453 + } 454 + 455 + return js_mknum((double)value); 456 + } 457 + 458 + // DataView.prototype.getInt32(byteOffset, littleEndian) 459 + static jsval_t js_dataview_getInt32(struct js *js, jsval_t *args, int nargs) { 460 + if (nargs < 1) return js_mkerr(js, "getInt32 requires byteOffset"); 461 + 462 + jsval_t this_val = js_getthis(js); 463 + jsval_t dv_data_val = js_get(js, this_val, "_dataview_data"); 464 + 465 + if (js_type(dv_data_val) != JS_NUM) { 466 + return js_mkerr(js, "Not a DataView"); 467 + } 468 + 469 + DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); 470 + size_t offset = (size_t)js_getnum(args[0]); 471 + bool little_endian = (nargs > 1 && js_truthy(js, args[1])); 472 + 473 + if (offset + 4 > dv->byte_length) { 474 + return js_mkerr(js, "Offset out of bounds"); 475 + } 476 + 477 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 478 + int32_t value; 479 + 480 + if (little_endian) { 481 + value = (int32_t)(ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24)); 482 + } else { 483 + value = (int32_t)((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]); 484 + } 485 + 486 + return js_mknum((double)value); 487 + } 488 + 489 + // DataView.prototype.getFloat32(byteOffset, littleEndian) 490 + static jsval_t js_dataview_getFloat32(struct js *js, jsval_t *args, int nargs) { 491 + if (nargs < 1) return js_mkerr(js, "getFloat32 requires byteOffset"); 492 + 493 + jsval_t this_val = js_getthis(js); 494 + jsval_t dv_data_val = js_get(js, this_val, "_dataview_data"); 495 + 496 + if (js_type(dv_data_val) != JS_NUM) { 497 + return js_mkerr(js, "Not a DataView"); 498 + } 499 + 500 + DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); 501 + size_t offset = (size_t)js_getnum(args[0]); 502 + bool little_endian = (nargs > 1 && js_truthy(js, args[1])); 503 + 504 + if (offset + 4 > dv->byte_length) { 505 + return js_mkerr(js, "Offset out of bounds"); 506 + } 507 + 508 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 509 + uint32_t bits; 510 + 511 + if (little_endian) { 512 + bits = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); 513 + } else { 514 + bits = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; 515 + } 516 + 517 + float value; 518 + memcpy(&value, &bits, 4); 519 + return js_mknum((double)value); 520 + } 521 + 522 + // Buffer.from(array/string/buffer) 523 + static jsval_t js_buffer_from(struct js *js, jsval_t *args, int nargs) { 524 + if (nargs < 1) { 525 + return js_mkerr(js, "Buffer.from requires at least one argument"); 526 + } 527 + 528 + if (js_type(args[0]) == JS_STR) { 529 + size_t len; 530 + char *str = js_getstr(js, args[0], &len); 531 + 532 + ArrayBufferData *buffer = create_array_buffer_data(len); 533 + if (!buffer) return js_mkerr(js, "Failed to allocate buffer"); 534 + 535 + memcpy(buffer->data, str, len); 536 + jsval_t obj = create_typed_array(js, TYPED_ARRAY_UINT8, buffer, 0, len, "Buffer"); 537 + js_set(js, obj, "toString", js_mkfun(js_buffer_toString)); 538 + js_set(js, obj, "toBase64", js_mkfun(js_buffer_toBase64)); 539 + js_set(js, obj, "write", js_mkfun(js_buffer_write)); 540 + return obj; 541 + } 542 + 543 + jsval_t length_val = js_get(js, args[0], "length"); 544 + if (js_type(length_val) == JS_NUM) { 545 + size_t len = (size_t)js_getnum(length_val); 546 + ArrayBufferData *buffer = create_array_buffer_data(len); 547 + if (!buffer) return js_mkerr(js, "Failed to allocate buffer"); 548 + 549 + for (size_t i = 0; i < len; i++) { 550 + char idx_str[32]; 551 + snprintf(idx_str, sizeof(idx_str), "%zu", i); 552 + jsval_t elem = js_get(js, args[0], idx_str); 553 + if (js_type(elem) == JS_NUM) { 554 + buffer->data[i] = (uint8_t)js_getnum(elem); 555 + } 556 + } 557 + 558 + jsval_t obj = create_typed_array(js, TYPED_ARRAY_UINT8, buffer, 0, len, "Buffer"); 559 + js_set(js, obj, "toString", js_mkfun(js_buffer_toString)); 560 + js_set(js, obj, "toBase64", js_mkfun(js_buffer_toBase64)); 561 + js_set(js, obj, "write", js_mkfun(js_buffer_write)); 562 + return obj; 563 + } 564 + 565 + return js_mkerr(js, "Invalid argument to Buffer.from"); 566 + } 567 + 568 + // Buffer.alloc(size) 569 + static jsval_t js_buffer_alloc(struct js *js, jsval_t *args, int nargs) { 570 + if (nargs < 1) { 571 + return js_mkerr(js, "Buffer.alloc requires a size argument"); 572 + } 573 + 574 + size_t size = (size_t)js_getnum(args[0]); 575 + ArrayBufferData *buffer = create_array_buffer_data(size); 576 + if (!buffer) return js_mkerr(js, "Failed to allocate buffer"); 577 + 578 + jsval_t obj = create_typed_array(js, TYPED_ARRAY_UINT8, buffer, 0, size, "Buffer"); 579 + js_set(js, obj, "toString", js_mkfun(js_buffer_toString)); 580 + js_set(js, obj, "toBase64", js_mkfun(js_buffer_toBase64)); 581 + js_set(js, obj, "write", js_mkfun(js_buffer_write)); 582 + 583 + return obj; 584 + } 585 + 586 + // Buffer.prototype.toString(encoding) 587 + static jsval_t js_buffer_toString(struct js *js, jsval_t *args, int nargs) { 588 + jsval_t this_val = js_getthis(js); 589 + jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 590 + 591 + if (js_type(ta_data_val) != JS_NUM) { 592 + return js_mkerr(js, "Not a Buffer"); 593 + } 594 + 595 + TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 596 + if (!ta_data) return js_mkerr(js, "Invalid Buffer"); 597 + 598 + char *encoding = "utf8"; 599 + if (nargs > 0 && js_type(args[0]) == JS_STR) { 600 + encoding = js_getstr(js, args[0], NULL); 601 + } 602 + 603 + uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 604 + size_t len = ta_data->byte_length; 605 + 606 + if (strcmp(encoding, "base64") == 0) { 607 + size_t out_len; 608 + char *encoded = base64_encode(data, len, &out_len); 609 + if (!encoded) return js_mkerr(js, "Failed to encode base64"); 610 + 611 + jsval_t result = js_mkstr(js, encoded, out_len); 612 + free(encoded); 613 + return result; 614 + } else if (strcmp(encoding, "hex") == 0) { 615 + char *hex = malloc(len * 2 + 1); 616 + if (!hex) return js_mkerr(js, "Failed to allocate hex string"); 617 + 618 + for (size_t i = 0; i < len; i++) { 619 + snprintf(hex + i * 2, 3, "%02x", data[i]); 620 + } 621 + 622 + jsval_t result = js_mkstr(js, hex, len * 2); 623 + free(hex); 624 + return result; 625 + } else return js_mkstr(js, data, len); 626 + } 627 + 628 + // Buffer.prototype.toBase64() 629 + static jsval_t js_buffer_toBase64(struct js *js, jsval_t *args, int nargs) { 630 + (void)args; (void)nargs; 631 + jsval_t encoding_arg = js_mkstr(js, "base64", 6); 632 + jsval_t new_args[1] = {encoding_arg}; 633 + return js_buffer_toString(js, new_args, 1); 634 + } 635 + 636 + // Buffer.prototype.write(string, offset, length, encoding) 637 + static jsval_t js_buffer_write(struct js *js, jsval_t *args, int nargs) { 638 + if (nargs < 1) return js_mkerr(js, "write requires a string"); 639 + 640 + jsval_t this_val = js_getthis(js); 641 + jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 642 + 643 + if (js_type(ta_data_val) != JS_NUM) { 644 + return js_mkerr(js, "Not a Buffer"); 645 + } 646 + 647 + TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 648 + if (!ta_data) return js_mkerr(js, "Invalid Buffer"); 649 + 650 + size_t str_len; 651 + char *str = js_getstr(js, args[0], &str_len); 652 + size_t offset = 0; 653 + size_t length = ta_data->byte_length; 654 + 655 + if (nargs > 1 && js_type(args[1]) == JS_NUM) { 656 + offset = (size_t)js_getnum(args[1]); 657 + } 658 + 659 + if (nargs > 2 && js_type(args[2]) == JS_NUM) { 660 + length = (size_t)js_getnum(args[2]); 661 + } 662 + 663 + if (offset >= ta_data->byte_length) { 664 + return js_mknum(0); 665 + } 666 + 667 + size_t available = ta_data->byte_length - offset; 668 + size_t to_write = (str_len < length) ? str_len : length; 669 + to_write = (to_write < available) ? to_write : available; 670 + 671 + memcpy(ta_data->buffer->data + ta_data->byte_offset + offset, str, to_write); 672 + return js_mknum((double)to_write); 673 + } 674 + 675 + void init_buffer_module() { 676 + struct js *js = rt->js; 677 + jsval_t glob = js_glob(js); 678 + 679 + jsval_t arraybuffer_constructor = js_mkfun(js_arraybuffer_constructor); 680 + jsval_t arraybuffer_proto = js_mkobj(js); 681 + js_set(js, arraybuffer_proto, "slice", js_mkfun(js_arraybuffer_slice)); 682 + js_set(js, arraybuffer_constructor, "prototype", arraybuffer_proto); 683 + js_set(js, glob, "ArrayBuffer", arraybuffer_constructor); 684 + 685 + #define SETUP_TYPEDARRAY(name) \ 686 + do { \ 687 + jsval_t name##_constructor = js_mkfun(js_##name##_constructor); \ 688 + jsval_t name##_proto = js_mkobj(js); \ 689 + js_set(js, name##_proto, "slice", js_mkfun(js_typedarray_slice)); \ 690 + js_set(js, name##_proto, "subarray", js_mkfun(js_typedarray_subarray)); \ 691 + js_set(js, name##_constructor, "prototype", name##_proto); \ 692 + js_set(js, glob, #name, name##_constructor); \ 693 + } while(0) 694 + 695 + SETUP_TYPEDARRAY(Int8Array); 696 + SETUP_TYPEDARRAY(Uint8Array); 697 + SETUP_TYPEDARRAY(Uint8ClampedArray); 698 + SETUP_TYPEDARRAY(Int16Array); 699 + SETUP_TYPEDARRAY(Uint16Array); 700 + SETUP_TYPEDARRAY(Int32Array); 701 + SETUP_TYPEDARRAY(Uint32Array); 702 + SETUP_TYPEDARRAY(Float32Array); 703 + SETUP_TYPEDARRAY(Float64Array); 704 + SETUP_TYPEDARRAY(BigInt64Array); 705 + SETUP_TYPEDARRAY(BigUint64Array); 706 + 707 + jsval_t dataview_constructor = js_mkfun(js_dataview_constructor); 708 + jsval_t dataview_proto = js_mkobj(js); 709 + js_set(js, dataview_proto, "getUint8", js_mkfun(js_dataview_getUint8)); 710 + js_set(js, dataview_proto, "setUint8", js_mkfun(js_dataview_setUint8)); 711 + js_set(js, dataview_proto, "getInt16", js_mkfun(js_dataview_getInt16)); 712 + js_set(js, dataview_proto, "getInt32", js_mkfun(js_dataview_getInt32)); 713 + js_set(js, dataview_proto, "getFloat32", js_mkfun(js_dataview_getFloat32)); 714 + js_set(js, dataview_constructor, "prototype", dataview_proto); 715 + js_set(js, glob, "DataView", dataview_constructor); 716 + 717 + jsval_t buffer_obj = js_mkobj(js); 718 + js_set(js, buffer_obj, "from", js_mkfun(js_buffer_from)); 719 + js_set(js, buffer_obj, "alloc", js_mkfun(js_buffer_alloc)); 720 + js_set(js, glob, "Buffer", buffer_obj); 721 + }
+197
tests/test_buffer.cjs
··· 1 + // Test Buffer and TypedArray implementations 2 + 3 + console.log('=== ArrayBuffer Tests ==='); 4 + 5 + // Test ArrayBuffer creation 6 + const ab = new ArrayBuffer(16); 7 + console.log('ArrayBuffer byteLength:', ab.byteLength); 8 + 9 + // Test ArrayBuffer slice 10 + const ab2 = ab.slice(4, 12); 11 + console.log('Sliced ArrayBuffer byteLength:', ab2.byteLength); 12 + 13 + console.log('\n=== TypedArray Tests ==='); 14 + 15 + // Test Uint8Array 16 + const u8 = new Uint8Array(8); 17 + console.log('Uint8Array length:', u8.length); 18 + console.log('Uint8Array byteLength:', u8.byteLength); 19 + console.log('Uint8Array BYTES_PER_ELEMENT:', u8.BYTES_PER_ELEMENT); 20 + 21 + // Test Int16Array 22 + const i16 = new Int16Array(4); 23 + console.log('Int16Array length:', i16.length); 24 + console.log('Int16Array byteLength:', i16.byteLength); 25 + console.log('Int16Array BYTES_PER_ELEMENT:', i16.BYTES_PER_ELEMENT); 26 + 27 + // Test Int32Array 28 + const i32 = new Int32Array(2); 29 + console.log('Int32Array length:', i32.length); 30 + console.log('Int32Array byteLength:', i32.byteLength); 31 + console.log('Int32Array BYTES_PER_ELEMENT:', i32.BYTES_PER_ELEMENT); 32 + 33 + // Test Float32Array 34 + const f32 = new Float32Array(4); 35 + console.log('Float32Array length:', f32.length); 36 + console.log('Float32Array byteLength:', f32.byteLength); 37 + console.log('Float32Array BYTES_PER_ELEMENT:', f32.BYTES_PER_ELEMENT); 38 + 39 + // Test Float64Array 40 + const f64 = new Float64Array(2); 41 + console.log('Float64Array length:', f64.length); 42 + console.log('Float64Array byteLength:', f64.byteLength); 43 + console.log('Float64Array BYTES_PER_ELEMENT:', f64.BYTES_PER_ELEMENT); 44 + 45 + // Test Uint16Array 46 + const u16 = new Uint16Array(4); 47 + console.log('Uint16Array length:', u16.length); 48 + console.log('Uint16Array BYTES_PER_ELEMENT:', u16.BYTES_PER_ELEMENT); 49 + 50 + // Test Uint32Array 51 + const u32 = new Uint32Array(2); 52 + console.log('Uint32Array length:', u32.length); 53 + console.log('Uint32Array BYTES_PER_ELEMENT:', u32.BYTES_PER_ELEMENT); 54 + 55 + // Test Int8Array 56 + const i8 = new Int8Array(8); 57 + console.log('Int8Array length:', i8.length); 58 + console.log('Int8Array BYTES_PER_ELEMENT:', i8.BYTES_PER_ELEMENT); 59 + 60 + // Test Uint8ClampedArray 61 + const u8c = new Uint8ClampedArray(8); 62 + console.log('Uint8ClampedArray length:', u8c.length); 63 + console.log('Uint8ClampedArray BYTES_PER_ELEMENT:', u8c.BYTES_PER_ELEMENT); 64 + 65 + // Test BigInt64Array 66 + const bi64 = new BigInt64Array(2); 67 + console.log('BigInt64Array length:', bi64.length); 68 + console.log('BigInt64Array BYTES_PER_ELEMENT:', bi64.BYTES_PER_ELEMENT); 69 + 70 + // Test BigUint64Array 71 + const bu64 = new BigUint64Array(2); 72 + console.log('BigUint64Array length:', bu64.length); 73 + console.log('BigUint64Array BYTES_PER_ELEMENT:', bu64.BYTES_PER_ELEMENT); 74 + 75 + console.log('\n=== TypedArray from ArrayBuffer ==='); 76 + 77 + // Create TypedArray views on same ArrayBuffer 78 + const buffer = new ArrayBuffer(16); 79 + const view8 = new Uint8Array(buffer); 80 + const view16 = new Uint16Array(buffer); 81 + const view32 = new Uint32Array(buffer); 82 + 83 + console.log('Buffer size:', buffer.byteLength); 84 + console.log('Uint8Array view length:', view8.length); 85 + console.log('Uint16Array view length:', view16.length); 86 + console.log('Uint32Array view length:', view32.length); 87 + 88 + // Test with offset 89 + const viewWithOffset = new Uint8Array(buffer, 4); 90 + console.log('View with offset length:', viewWithOffset.length); 91 + console.log('View with offset byteOffset:', viewWithOffset.byteOffset); 92 + 93 + // Test with offset and length 94 + const viewWithOffsetAndLength = new Uint8Array(buffer, 4, 8); 95 + console.log('View with offset and length:', viewWithOffsetAndLength.length); 96 + console.log('View with offset and length byteOffset:', viewWithOffsetAndLength.byteOffset); 97 + 98 + console.log('\n=== DataView Tests ==='); 99 + 100 + // Test DataView creation 101 + const dv = new DataView(buffer); 102 + console.log('DataView byteLength:', dv.byteLength); 103 + console.log('DataView byteOffset:', dv.byteOffset); 104 + 105 + // Test DataView with offset 106 + const dv2 = new DataView(buffer, 4); 107 + console.log('DataView with offset byteLength:', dv2.byteLength); 108 + console.log('DataView with offset byteOffset:', dv2.byteOffset); 109 + 110 + // Test DataView with offset and length 111 + const dv3 = new DataView(buffer, 4, 8); 112 + console.log('DataView with offset and length byteLength:', dv3.byteLength); 113 + console.log('DataView with offset and length byteOffset:', dv3.byteOffset); 114 + 115 + // Test DataView get/set operations 116 + dv.setUint8(0, 42); 117 + const val = dv.getUint8(0); 118 + console.log('Set/Get Uint8:', val); 119 + 120 + // Test Int16 operations 121 + dv.setUint8(0, 0x12); 122 + dv.setUint8(1, 0x34); 123 + const int16LE = dv.getInt16(0, true); // little endian 124 + const int16BE = dv.getInt16(0, false); // big endian 125 + console.log('Int16 little endian:', int16LE.toString(16)); 126 + console.log('Int16 big endian:', int16BE.toString(16)); 127 + 128 + // Test Int32 operations 129 + dv.setUint8(0, 0x12); 130 + dv.setUint8(1, 0x34); 131 + dv.setUint8(2, 0x56); 132 + dv.setUint8(3, 0x78); 133 + const int32LE = dv.getInt32(0, true); 134 + const int32BE = dv.getInt32(0, false); 135 + console.log('Int32 little endian:', int32LE.toString(16)); 136 + console.log('Int32 big endian:', int32BE.toString(16)); 137 + 138 + // Test Float32 operations 139 + dv.setUint8(0, 0x3f); 140 + dv.setUint8(1, 0x80); 141 + dv.setUint8(2, 0x00); 142 + dv.setUint8(3, 0x00); 143 + const float32 = dv.getFloat32(0, false); // 1.0 in IEEE 754 144 + console.log('Float32:', float32); 145 + 146 + console.log('\n=== Buffer Tests (Node.js-style) ==='); 147 + 148 + // Test Buffer.alloc 149 + const buf1 = Buffer.alloc(10); 150 + console.log('Buffer.alloc length:', buf1.length); 151 + console.log('Buffer.alloc byteLength:', buf1.byteLength); 152 + 153 + // Test Buffer.from with string 154 + const buf2 = Buffer.from('Hello'); 155 + console.log('Buffer.from string length:', buf2.length); 156 + console.log('Buffer.from string toString:', buf2.toString()); 157 + 158 + // Test Buffer.from with array 159 + const buf3 = Buffer.from([72, 101, 108, 108, 111]); 160 + console.log('Buffer.from array length:', buf3.length); 161 + console.log('Buffer.from array toString:', buf3.toString()); 162 + 163 + // Test Buffer write 164 + const buf4 = Buffer.alloc(10); 165 + const written = buf4.write('Hello', 0); 166 + console.log('Bytes written:', written); 167 + console.log('Buffer after write:', buf4.toString()); 168 + 169 + // Test Buffer toString with hex encoding 170 + const buf5 = Buffer.from('Hello'); 171 + console.log('Buffer toString hex:', buf5.toString('hex')); 172 + 173 + // Test Buffer toString with base64 encoding 174 + const buf6 = Buffer.from('Hello World'); 175 + const base64 = buf6.toString('base64'); 176 + console.log('Buffer toString base64:', base64); 177 + 178 + // Test Buffer.toBase64 method 179 + const buf7 = Buffer.from('Test'); 180 + const base64_2 = buf7.toBase64(); 181 + console.log('Buffer.toBase64():', base64_2); 182 + 183 + console.log('\n=== TypedArray slice and subarray ==='); 184 + 185 + // Test slice (creates a copy) 186 + const original = new Uint8Array(10); 187 + const sliced = original.slice(2, 8); 188 + console.log('Original length:', original.length); 189 + console.log('Sliced length:', sliced.length); 190 + console.log('Sliced byteOffset:', sliced.byteOffset); 191 + 192 + // Test subarray (creates a view) 193 + const subarrayed = original.subarray(2, 8); 194 + console.log('Subarray length:', subarrayed.length); 195 + console.log('Subarray byteOffset:', subarrayed.byteOffset); 196 + 197 + console.log('\n=== All tests completed ===');