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.

ByteLengthQueuingStrategy/CountQueuingStrategy

+237 -64
+82
examples/spec/streams-queuing.js
··· 1 + import { test, testThrows, summary } from './helpers.js'; 2 + 3 + console.log('CountQueuingStrategy / ByteLengthQueuingStrategy Tests\n'); 4 + 5 + const cqs = new CountQueuingStrategy({ highWaterMark: 5 }); 6 + test('CQS highWaterMark', cqs.highWaterMark, 5); 7 + test('CQS size returns function', typeof cqs.size, 'function'); 8 + test('CQS size() returns 1', cqs.size(), 1); 9 + test('CQS size(anything) returns 1', cqs.size({ byteLength: 1024 }), 1); 10 + 11 + const cqs0 = new CountQueuingStrategy({ highWaterMark: 0 }); 12 + test('CQS highWaterMark 0', cqs0.highWaterMark, 0); 13 + 14 + const cqs_large = new CountQueuingStrategy({ highWaterMark: 1024 }); 15 + test('CQS highWaterMark 1024', cqs_large.highWaterMark, 1024); 16 + 17 + test('CQS size is same function each access', cqs.size === cqs.size, true); 18 + test('CQS size is same across instances', cqs.size === cqs_large.size, true); 19 + test('CQS size.name', cqs.size.name, 'size'); 20 + test('CQS size.length', cqs.size.length, 0); 21 + 22 + testThrows('CQS requires new', () => CountQueuingStrategy({ highWaterMark: 1 })); 23 + testThrows('CQS requires options', () => new CountQueuingStrategy()); 24 + testThrows('CQS requires highWaterMark', () => new CountQueuingStrategy({})); 25 + testThrows('CQS rejects null', () => new CountQueuingStrategy(null)); 26 + testThrows('CQS rejects non-object', () => new CountQueuingStrategy(5)); 27 + 28 + test('CQS typeof', typeof CountQueuingStrategy, 'function'); 29 + 30 + const blqs = new ByteLengthQueuingStrategy({ highWaterMark: 1024 }); 31 + test('BLQS highWaterMark', blqs.highWaterMark, 1024); 32 + test('BLQS size returns function', typeof blqs.size, 'function'); 33 + 34 + test('BLQS size with byteLength', blqs.size({ byteLength: 256 }), 256); 35 + test('BLQS size with byteLength 0', blqs.size({ byteLength: 0 }), 0); 36 + test('BLQS size with no byteLength', blqs.size({}), undefined); 37 + test('BLQS size.name', blqs.size.name, 'size'); 38 + test('BLQS size.length', blqs.size.length, 1); 39 + 40 + testThrows('BLQS size with undefined', () => blqs.size()); 41 + testThrows('BLQS size with null', () => blqs.size(null)); 42 + 43 + const blqs0 = new ByteLengthQueuingStrategy({ highWaterMark: 0 }); 44 + test('BLQS highWaterMark 0', blqs0.highWaterMark, 0); 45 + 46 + test('BLQS size is same function each access', blqs.size === blqs.size, true); 47 + test('BLQS size is same across instances', blqs.size === blqs0.size, true); 48 + 49 + testThrows('BLQS requires new', () => ByteLengthQueuingStrategy({ highWaterMark: 1 })); 50 + testThrows('BLQS requires options', () => new ByteLengthQueuingStrategy()); 51 + testThrows('BLQS requires highWaterMark', () => new ByteLengthQueuingStrategy({})); 52 + 53 + test('BLQS typeof', typeof ByteLengthQueuingStrategy, 'function'); 54 + test('CQS size !== BLQS size', cqs.size !== blqs.size, true); 55 + 56 + test('CQS toStringTag', Object.prototype.toString.call(cqs), '[object CountQueuingStrategy]'); 57 + test('BLQS toStringTag', Object.prototype.toString.call(blqs), '[object ByteLengthQueuingStrategy]'); 58 + 59 + const cqs_str = new CountQueuingStrategy({ highWaterMark: '10' }); 60 + test('CQS highWaterMark string coercion', cqs_str.highWaterMark, 10); 61 + 62 + const blqs_str = new ByteLengthQueuingStrategy({ highWaterMark: '256' }); 63 + test('BLQS highWaterMark string coercion', blqs_str.highWaterMark, 256); 64 + 65 + test('CQS highWaterMark false coercion', new CountQueuingStrategy({ highWaterMark: false }).highWaterMark, 0); 66 + test('CQS highWaterMark true coercion', new CountQueuingStrategy({ highWaterMark: true }).highWaterMark, 1); 67 + 68 + const cqs_frac = new CountQueuingStrategy({ highWaterMark: 2.5 }); 69 + test('CQS fractional highWaterMark', cqs_frac.highWaterMark, 2.5); 70 + 71 + const buf = new Uint8Array([1, 2, 3, 4]); 72 + test('BLQS size with Uint8Array', blqs.size(buf), 4); 73 + 74 + testThrows('BLQS size propagates getter throw', () => { 75 + blqs.size({ 76 + get byteLength() { 77 + throw new Error('boom'); 78 + } 79 + }); 80 + }); 81 + 82 + summary();
+26 -11
include/internal.h
··· 5 5 #include "object.h" 6 6 #include "pool.h" 7 7 #include "arena.h" 8 + #include "descriptors.h" 8 9 #include "esm/loader.h" 9 10 10 11 #include <assert.h> ··· 214 215 }; 215 216 216 217 typedef struct { 218 + ant_offset_t len; 219 + char bytes[]; 220 + } ant_flat_string_t; 221 + 222 + typedef struct { 223 + ant_offset_t len; 224 + uint8_t depth; 225 + ant_value_t left; 226 + ant_value_t right; 227 + ant_value_t cached; 228 + } ant_rope_heap_t; 229 + 230 + typedef struct { 217 231 const char *ptr; 218 232 size_t len; 219 233 bool needs_free; ··· 361 375 return vtype(value) == T_STR && ((vdata(value) & 1ULL) != 0); 362 376 } 363 377 364 - typedef struct { 365 - ant_offset_t len; 366 - char bytes[]; 367 - } ant_flat_string_t; 378 + static inline ant_value_t js_make_ctor(ant_t *js, ant_cfunc_t fn, ant_value_t proto, const char *name, size_t nlen) { 379 + ant_value_t obj = js_mkobj(js); 380 + js_set_slot(obj, SLOT_CFUNC, js_mkfun(fn)); 381 + js_mkprop_fast(js, obj, "prototype", 9, proto); 382 + js_mkprop_fast(js, obj, "name", 4, js_mkstr(js, name, nlen)); 383 + js_set_descriptor(js, obj, "name", 4, 0); 384 + 385 + ant_value_t fn_val = js_obj_to_func(obj); 386 + js_set(js, proto, "constructor", fn_val); 387 + js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 368 388 369 - typedef struct { 370 - ant_offset_t len; 371 - uint8_t depth; 372 - ant_value_t left; 373 - ant_value_t right; 374 - ant_value_t cached; 375 - } ant_rope_heap_t; 389 + return fn_val; 390 + } 376 391 377 392 #endif
+6
include/streams/queuing.h
··· 1 + #ifndef STREAMS_QUEUING_H 2 + #define STREAMS_QUEUING_H 3 + 4 + void init_queuing_strategies_module(void); 5 + 6 + #endif
+2 -2
sources.json
··· 1 1 { 2 2 "engine": { 3 - "patterns": ["src/*.c", "src/gc/*.c", "src/highlight/*.c", "src/esm/*.c", "src/cli/*.c", "src/modules/*.c", "src/silver/*.c"], 3 + "patterns": ["src/*.c", "src/gc/*.c", "src/highlight/*.c", "src/esm/*.c", "src/cli/*.c", "src/modules/*.c", "src/streams/*.c", "src/silver/*.c"], 4 4 "exclude": ["src/main.c", "src/watch.c"] 5 5 }, 6 6 "library": { 7 - "patterns": ["src/*.c", "src/gc/*.c", "src/highlight/*.c", "src/esm/*.c", "src/modules/*.c", "src/silver/*.c"], 7 + "patterns": ["src/*.c", "src/gc/*.c", "src/highlight/*.c", "src/esm/*.c", "src/modules/*.c", "src/streams/*.c", "src/silver/*.c"], 8 8 "exclude": ["src/main.c", "src/watch.c"] 9 9 }, 10 10 "core": {
+2
src/main.c
··· 79 79 #include "modules/headers.h" 80 80 #include "modules/blob.h" 81 81 #include "modules/formdata.h" 82 + #include "streams/queuing.h" 82 83 83 84 int js_result = EXIT_SUCCESS; 84 85 typedef int (*cmd_fn)(int argc, char **argv); ··· 595 596 init_date_module(); 596 597 init_regex_module(); 597 598 init_collections_module(); 599 + init_queuing_strategies_module(); 598 600 init_builtin_module(); 599 601 init_buffer_module(); 600 602 init_fs_module();
+2 -16
src/modules/blob.c
··· 405 405 return obj; 406 406 } 407 407 408 - static ant_value_t make_ctor(ant_t *js, ant_cfunc_t fn, ant_value_t proto, const char *name, size_t nlen) { 409 - ant_value_t obj = js_mkobj(js); 410 - js_set_slot(obj, SLOT_CFUNC, js_mkfun(fn)); 411 - js_mkprop_fast(js, obj, "prototype", 9, proto); 412 - js_mkprop_fast(js, obj, "name", 4, js_mkstr(js, name, nlen)); 413 - js_set_descriptor(js, obj, "name", 4, 0); 414 - 415 - ant_value_t fn_val = js_obj_to_func(obj); 416 - js_set(js, proto, "constructor", fn_val); 417 - js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 418 - 419 - return fn_val; 420 - } 421 - 422 408 void init_blob_module(void) { 423 409 ant_t *js = rt->js; 424 410 ant_value_t g = js_glob(js); ··· 434 420 js_set(js, g_blob_proto, "stream", js_mkfun(js_blob_stream)); 435 421 436 422 js_set_sym(js, g_blob_proto, get_toStringTag_sym(), js_mkstr(js, "Blob", 4)); 437 - ant_value_t blob_ctor = make_ctor(js, js_blob_ctor, g_blob_proto, "Blob", 4); 423 + ant_value_t blob_ctor = js_make_ctor(js, js_blob_ctor, g_blob_proto, "Blob", 4); 438 424 439 425 js_set(js, g, "Blob", blob_ctor); 440 426 js_set_descriptor(js, g, "Blob", 4, JS_DESC_W | JS_DESC_C); ··· 446 432 js_set_getter_desc(js, g_file_proto, "lastModified", 12, js_mkfun(file_get_last_modified), JS_DESC_C); 447 433 448 434 js_set_sym(js, g_file_proto, get_toStringTag_sym(), js_mkstr(js, "File", 4)); 449 - ant_value_t file_ctor = make_ctor(js, js_file_ctor, g_file_proto, "File", 4); 435 + ant_value_t file_ctor = js_make_ctor(js, js_file_ctor, g_file_proto, "File", 4); 450 436 451 437 js_set(js, g, "File", file_ctor); 452 438 js_set_descriptor(js, g, "File", 4, JS_DESC_W | JS_DESC_C);
+4 -19
src/modules/events.c
··· 631 631 return result; 632 632 } 633 633 634 - static ant_value_t make_event_ctor(ant_t *js, ant_cfunc_t fn, ant_value_t proto, const char *name, size_t nlen) { 635 - ant_value_t ctor_obj = js_mkobj(js); 636 - js_set_slot(ctor_obj, SLOT_CFUNC, js_mkfun(fn)); 637 - 638 - js_mkprop_fast(js, ctor_obj, "prototype", 9, proto); 639 - js_mkprop_fast(js, ctor_obj, "name", 4, js_mkstr(js, name, nlen)); 640 - js_set_descriptor(js, ctor_obj, "name", 4, 0); 641 - 642 - ant_value_t fn_val = js_obj_to_func(ctor_obj); 643 - js_set(js, proto, "constructor", fn_val); 644 - js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 645 - 646 - return fn_val; 647 - } 648 - 649 634 ant_value_t events_library(ant_t *js) { 650 635 ant_value_t lib = js_mkobj(js); 651 636 ant_value_t eventemitter_ctor = js_mkobj(js); ··· 691 676 js_set(js, g_event_proto, "AT_TARGET", js_mknum(2)); 692 677 js_set(js, g_event_proto, "BUBBLING_PHASE", js_mknum(3)); 693 678 694 - ant_value_t event_fn = make_event_ctor(js, js_event_ctor, g_event_proto, "Event", 5); 679 + ant_value_t event_fn = js_make_ctor(js, js_event_ctor, g_event_proto, "Event", 5); 695 680 js_set(js, event_fn, "NONE", js_mknum(0)); 696 681 js_set(js, event_fn, "CAPTURING_PHASE", js_mknum(1)); 697 682 js_set(js, event_fn, "AT_TARGET", js_mknum(2)); ··· 702 687 js_set_proto_init(g_customevent_proto, g_event_proto); 703 688 js_set_sym(js, g_customevent_proto, get_toStringTag_sym(), js_mkstr(js, "CustomEvent", 11)); 704 689 705 - ant_value_t customevent_fn = make_event_ctor(js, js_customevent_ctor, g_customevent_proto, "CustomEvent", 11); 690 + ant_value_t customevent_fn = js_make_ctor(js, js_customevent_ctor, g_customevent_proto, "CustomEvent", 11); 706 691 js_set(js, global, "CustomEvent", customevent_fn); 707 692 708 693 g_errorevent_proto = js_mkobj(js); 709 694 js_set_proto_init(g_errorevent_proto, g_event_proto); 710 695 js_set_sym(js, g_errorevent_proto, get_toStringTag_sym(), js_mkstr(js, "ErrorEvent", 10)); 711 696 712 - ant_value_t errorevent_fn = make_event_ctor(js, js_errorevent_ctor, g_errorevent_proto, "ErrorEvent", 10); 697 + ant_value_t errorevent_fn = js_make_ctor(js, js_errorevent_ctor, g_errorevent_proto, "ErrorEvent", 10); 713 698 js_set(js, global, "ErrorEvent", errorevent_fn); 714 699 715 700 g_promiserejectionevent_proto = js_mkobj(js); 716 701 js_set_proto_init(g_promiserejectionevent_proto, g_event_proto); 717 702 js_set_sym(js, g_promiserejectionevent_proto, get_toStringTag_sym(), js_mkstr(js, "PromiseRejectionEvent", 21)); 718 703 719 - ant_value_t pre_fn = make_event_ctor(js, js_promiserejectionevent_ctor, g_promiserejectionevent_proto, "PromiseRejectionEvent", 21); 704 + ant_value_t pre_fn = js_make_ctor(js, js_promiserejectionevent_ctor, g_promiserejectionevent_proto, "PromiseRejectionEvent", 21); 720 705 js_set(js, global, "PromiseRejectionEvent", pre_fn); 721 706 722 707 ant_value_t eventtarget_proto = js_mkobj(js);
+2 -16
src/modules/textcodec.c
··· 111 111 return false; 112 112 } 113 113 114 - static ant_value_t make_ctor(ant_t *js, ant_cfunc_t fn, ant_value_t proto, const char *name, size_t nlen) { 115 - ant_value_t obj = js_mkobj(js); 116 - js_set_slot(obj, SLOT_CFUNC, js_mkfun(fn)); 117 - js_mkprop_fast(js, obj, "prototype", 9, proto); 118 - js_mkprop_fast(js, obj, "name", 4, js_mkstr(js, name, nlen)); 119 - js_set_descriptor(js, obj, "name", 4, 0); 120 - 121 - ant_value_t fn_val = js_obj_to_func(obj); 122 - js_set(js, proto, "constructor", fn_val); 123 - js_set_descriptor(js, proto, "constructor", 11, JS_DESC_W | JS_DESC_C); 124 - 125 - return fn_val; 126 - } 127 - 128 114 static ant_value_t js_textencoder_get_encoding(ant_t *js, ant_value_t *args, int nargs) { 129 115 return js_mkstr(js, "utf-8", 5); 130 116 } ··· 441 427 js_set(js, g_textencoder_proto, "encodeInto", js_mkfun(js_textencoder_encode_into)); 442 428 js_set_sym(js, g_textencoder_proto, get_toStringTag_sym(), js_mkstr(js, "TextEncoder", 11)); 443 429 444 - ant_value_t te_ctor = make_ctor(js, js_textencoder_ctor, g_textencoder_proto, "TextEncoder", 11); 430 + ant_value_t te_ctor = js_make_ctor(js, js_textencoder_ctor, g_textencoder_proto, "TextEncoder", 11); 445 431 js_set(js, g, "TextEncoder", te_ctor); 446 432 js_set_descriptor(js, g, "TextEncoder", 11, JS_DESC_W | JS_DESC_C); 447 433 ··· 452 438 js_set(js, g_textdecoder_proto, "decode", js_mkfun(js_textdecoder_decode)); 453 439 js_set_sym(js, g_textdecoder_proto, get_toStringTag_sym(), js_mkstr(js, "TextDecoder", 11)); 454 440 455 - ant_value_t td_ctor = make_ctor(js, js_textdecoder_ctor, g_textdecoder_proto, "TextDecoder", 11); 441 + ant_value_t td_ctor = js_make_ctor(js, js_textdecoder_ctor, g_textdecoder_proto, "TextDecoder", 11); 456 442 js_set(js, g, "TextDecoder", td_ctor); 457 443 js_set_descriptor(js, g, "TextDecoder", 11, JS_DESC_W | JS_DESC_C); 458 444 }
+111
src/streams/queuing.c
··· 1 + #include <string.h> 2 + 3 + #include "ant.h" 4 + #include "errors.h" 5 + #include "runtime.h" 6 + #include "internal.h" 7 + #include "descriptors.h" 8 + 9 + #include "modules/symbol.h" 10 + #include "streams/queuing.h" 11 + 12 + static ant_value_t g_count_qs_proto; 13 + static ant_value_t g_bytelength_qs_proto; 14 + 15 + static ant_value_t js_count_size(ant_t *js, ant_value_t *args, int nargs) { 16 + return js_mknum(1); 17 + } 18 + 19 + static ant_value_t js_bytelength_size(ant_t *js, ant_value_t *args, int nargs) { 20 + if (nargs < 1 || vtype(args[0]) == T_UNDEF || is_null(args[0])) 21 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot get property 'byteLength' of undefined or null"); 22 + if (!is_object_type(args[0])) return js_mkundef(); 23 + 24 + ant_value_t bl = js_get(js, args[0], "byteLength"); 25 + if (is_err(bl)) return bl; 26 + if (vtype(bl) == T_NUM) return bl; 27 + 28 + return js_mkundef(); 29 + } 30 + 31 + static ant_value_t js_qs_get_highwatermark(ant_t *js, ant_value_t *args, int nargs) { 32 + ant_value_t s = js_get_slot(js->this_val, SLOT_DATA); 33 + if (vtype(s) == T_NUM) return s; 34 + return js_mkundef(); 35 + } 36 + 37 + static ant_value_t js_qs_get_size(ant_t *js, ant_value_t *args, int nargs) { 38 + ant_value_t proto = js_get_proto(js, js->this_val); 39 + return js_get_slot(proto, SLOT_DATA); 40 + } 41 + 42 + static ant_value_t qs_ctor(ant_t *js, ant_value_t *args, int nargs, ant_value_t proto, const char *name) { 43 + if (vtype(js->new_target) == T_UNDEF) 44 + return js_mkerr_typed(js, JS_ERR_TYPE, "%s constructor requires 'new'", name); 45 + 46 + if (nargs < 1 || vtype(args[0]) == T_UNDEF || is_null(args[0])) 47 + return js_mkerr_typed(js, JS_ERR_TYPE, "Failed to construct '%s': 1 argument required", name); 48 + 49 + if (!is_object_type(args[0])) 50 + return js_mkerr_typed(js, JS_ERR_TYPE, "Failed to construct '%s': argument is not an object", name); 51 + 52 + ant_value_t hv = js_get(js, args[0], "highWaterMark"); 53 + if (is_err(hv)) return hv; 54 + if (vtype(hv) == T_UNDEF) 55 + return js_mkerr_typed(js, JS_ERR_TYPE, "Failed to construct '%s': member highWaterMark is required", name); 56 + 57 + double hwm = js_to_number(js, hv); 58 + 59 + ant_value_t obj = js_mkobj(js); 60 + ant_value_t resolved = js_instance_proto_from_new_target(js, proto); 61 + 62 + if (is_object_type(resolved)) js_set_proto_init(obj, resolved); 63 + js_set_slot(obj, SLOT_DATA, js_mknum(hwm)); 64 + 65 + return obj; 66 + } 67 + 68 + static ant_value_t js_count_qs_ctor(ant_t *js, ant_value_t *args, int nargs) { 69 + return qs_ctor(js, args, nargs, g_count_qs_proto, "CountQueuingStrategy"); 70 + } 71 + 72 + static ant_value_t js_bytelength_qs_ctor(ant_t *js, ant_value_t *args, int nargs) { 73 + return qs_ctor(js, args, nargs, g_bytelength_qs_proto, "ByteLengthQueuingStrategy"); 74 + } 75 + 76 + static ant_value_t make_size_fn(ant_t *js, ant_cfunc_t cfunc, int length) { 77 + ant_value_t obj = js_mkobj(js); 78 + 79 + js_set_slot(obj, SLOT_CFUNC, js_mkfun(cfunc)); 80 + js_mkprop_fast(js, obj, "name", 4, js_mkstr(js, "size", 4)); 81 + js_set_descriptor(js, obj, "name", 4, 0); 82 + js_mkprop_fast(js, obj, "length", 6, js_mknum(length)); 83 + js_set_descriptor(js, obj, "length", 6, 0); 84 + 85 + return js_obj_to_func(obj); 86 + } 87 + 88 + void init_queuing_strategies_module(void) { 89 + ant_t *js = rt->js; 90 + ant_value_t g = js_glob(js); 91 + 92 + g_count_qs_proto = js_mkobj(js); 93 + js_set_slot(g_count_qs_proto, SLOT_DATA, make_size_fn(js, js_count_size, 0)); 94 + js_set_getter_desc(js, g_count_qs_proto, "highWaterMark", 13, js_mkfun(js_qs_get_highwatermark), JS_DESC_C); 95 + js_set_getter_desc(js, g_count_qs_proto, "size", 4, js_mkfun(js_qs_get_size), JS_DESC_C); 96 + js_set_sym(js, g_count_qs_proto, get_toStringTag_sym(), js_mkstr(js, "CountQueuingStrategy", 20)); 97 + 98 + ant_value_t cqs_ctor = js_make_ctor(js, js_count_qs_ctor, g_count_qs_proto, "CountQueuingStrategy", 20); 99 + js_set(js, g, "CountQueuingStrategy", cqs_ctor); 100 + js_set_descriptor(js, g, "CountQueuingStrategy", 20, JS_DESC_W | JS_DESC_C); 101 + 102 + g_bytelength_qs_proto = js_mkobj(js); 103 + js_set_slot(g_bytelength_qs_proto, SLOT_DATA, make_size_fn(js, js_bytelength_size, 1)); 104 + js_set_getter_desc(js, g_bytelength_qs_proto, "highWaterMark", 13, js_mkfun(js_qs_get_highwatermark), JS_DESC_C); 105 + js_set_getter_desc(js, g_bytelength_qs_proto, "size", 4, js_mkfun(js_qs_get_size), JS_DESC_C); 106 + js_set_sym(js, g_bytelength_qs_proto, get_toStringTag_sym(), js_mkstr(js, "ByteLengthQueuingStrategy", 25)); 107 + 108 + ant_value_t blqs_ctor = js_make_ctor(js, js_bytelength_qs_ctor, g_bytelength_qs_proto, "ByteLengthQueuingStrategy", 25); 109 + js_set(js, g, "ByteLengthQueuingStrategy", blqs_ctor); 110 + js_set_descriptor(js, g, "ByteLengthQueuingStrategy", 25, JS_DESC_W | JS_DESC_C); 111 + }