Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042#include <stdlib.h>#include <string.h>
#include "ant.h"#include "errors.h"#include "runtime.h"#include "internal.h"#include "descriptors.h"
#include "silver/engine.h"#include "modules/symbol.h"#include "modules/assert.h"#include "streams/readable.h"#include "streams/pipes.h"
ant_value_t g_rs_proto;ant_value_t g_reader_proto;ant_value_t g_controller_proto;ant_value_t g_rs_async_iter_proto;
bool rs_is_stream(ant_value_t obj) { return js_check_brand(obj, BRAND_READABLE_STREAM) && rs_get_stream(obj) != NULL;}
bool rs_is_reader(ant_value_t obj) { return js_check_brand(obj, BRAND_READABLE_STREAM_READER) && vtype(js_get_slot(obj, SLOT_RS_CLOSED)) == T_PROMISE && vtype(js_get_slot(obj, SLOT_AUX)) == T_ARR;}
bool rs_is_controller(ant_value_t obj) { return js_check_brand(obj, BRAND_READABLE_STREAM_CONTROLLER) && rs_get_controller(obj) != NULL && rs_is_stream(js_get_slot(obj, SLOT_ENTRIES));}
bool rs_stream_locked(ant_value_t stream_obj) { return rs_is_stream(stream_obj) && rs_is_reader(rs_stream_reader(stream_obj));}
bool rs_stream_disturbed(ant_value_t stream_obj) { rs_stream_t *stream = rs_get_stream(stream_obj); return stream && stream->disturbed;}
bool rs_stream_unusable(ant_value_t stream_obj) { return rs_stream_locked(stream_obj) || rs_stream_disturbed(stream_obj);}
rs_stream_t *rs_get_stream(ant_value_t obj) { ant_value_t s = js_get_slot(obj, SLOT_DATA); if (vtype(s) != T_NUM) return NULL; return (rs_stream_t *)(uintptr_t)(size_t)js_getnum(s);}
rs_controller_t *rs_get_controller(ant_value_t obj) { ant_value_t s = js_get_slot(obj, SLOT_DATA); if (vtype(s) != T_NUM) return NULL; return (rs_controller_t *)(uintptr_t)(size_t)js_getnum(s);}
static void rs_stream_finalize(ant_t *js, ant_object_t *obj) { if (!obj->extra_slots) return; ant_extra_slot_t *entries = (ant_extra_slot_t *)obj->extra_slots; for (uint8_t i = 0; i < obj->extra_count; i++) { if (entries[i].slot == SLOT_DATA && vtype(entries[i].value) == T_NUM) { free((rs_stream_t *)(uintptr_t)(size_t)js_getnum(entries[i].value)); return; }}}
static void rs_controller_finalize(ant_t *js, ant_object_t *obj) { if (!obj->extra_slots) return; ant_extra_slot_t *entries = (ant_extra_slot_t *)obj->extra_slots; for (uint8_t i = 0; i < obj->extra_count; i++) { if (entries[i].slot == SLOT_DATA && vtype(entries[i].value) == T_NUM) { rs_controller_t *ctrl = (rs_controller_t *)(uintptr_t)(size_t)js_getnum(entries[i].value); free(ctrl->queue_sizes); free(ctrl); return; }}}
ant_value_t rs_stream_controller(ant_t *js, ant_value_t stream_obj) { return js_get_slot(stream_obj, SLOT_ENTRIES);}
ant_value_t rs_stream_reader(ant_value_t stream_obj) { return js_get_slot(stream_obj, SLOT_CTOR);}
ant_value_t rs_stream_error(ant_value_t stream_obj) { return js_get_slot(stream_obj, SLOT_AUX);}
static inline ant_value_t rs_ctrl_stream(ant_value_t ctrl_obj) { return js_get_slot(ctrl_obj, SLOT_ENTRIES);}
static inline ant_value_t rs_ctrl_pull(ant_value_t ctrl_obj) { return js_get_slot(ctrl_obj, SLOT_RS_PULL);}
static inline ant_value_t rs_ctrl_cancel(ant_value_t ctrl_obj) { return js_get_slot(ctrl_obj, SLOT_RS_CANCEL);}
ant_value_t rs_ctrl_size(ant_value_t ctrl_obj) { return js_get_slot(ctrl_obj, SLOT_RS_SIZE);}
static inline ant_value_t rs_ctrl_queue(ant_t *js, ant_value_t ctrl_obj) { return js_get_slot(ctrl_obj, SLOT_AUX);}
ant_value_t rs_reader_stream(ant_value_t reader_obj) { return js_get_slot(reader_obj, SLOT_ENTRIES);}
ant_value_t rs_reader_closed(ant_value_t reader_obj) { return js_get_slot(reader_obj, SLOT_RS_CLOSED);}
ant_value_t rs_reader_reqs(ant_value_t reader_obj) { return js_get_slot(reader_obj, SLOT_AUX);}
bool rs_reader_has_reqs(ant_t *js, ant_value_t reader_obj) { ant_value_t arr = rs_reader_reqs(reader_obj); return vtype(arr) == T_ARR && js_arr_len(js, arr) > 0;}
void rs_ctrl_queue_push(ant_t *js, ant_value_t ctrl_obj, ant_value_t value) { ant_value_t arr = rs_ctrl_queue(js, ctrl_obj); if (vtype(arr) == T_ARR) js_arr_push(js, arr, value);}
static ant_value_t rs_ctrl_queue_shift(ant_t *js, ant_value_t ctrl_obj) { ant_value_t arr = rs_ctrl_queue(js, ctrl_obj); if (vtype(arr) != T_ARR) return js_mkundef(); ant_object_t *aobj = js_obj_ptr(arr); if (aobj->u.array.len == 0) return js_mkundef(); ant_value_t val = aobj->u.array.data[0]; uint32_t new_len = aobj->u.array.len - 1; for (uint32_t i = 0; i < new_len; i++) aobj->u.array.data[i] = aobj->u.array.data[i + 1]; aobj->u.array.len = new_len; return val;}
ant_offset_t rs_ctrl_queue_len(ant_t *js, ant_value_t ctrl_obj) { ant_value_t arr = rs_ctrl_queue(js, ctrl_obj); if (vtype(arr) != T_ARR) return 0; return js_arr_len(js, arr);}
static void rs_reader_reqs_push(ant_t *js, ant_value_t reader_obj, ant_value_t promise) { ant_value_t arr = rs_reader_reqs(reader_obj); if (vtype(arr) == T_ARR) js_arr_push(js, arr, promise);}
static ant_value_t rs_reader_reqs_shift(ant_t *js, ant_value_t reader_obj) { ant_value_t arr = rs_reader_reqs(reader_obj); if (vtype(arr) != T_ARR) return js_mkundef(); ant_object_t *aobj = js_obj_ptr(arr); if (aobj->u.array.len == 0) return js_mkundef(); ant_value_t val = aobj->u.array.data[0]; uint32_t new_len = aobj->u.array.len - 1; for (uint32_t i = 0; i < new_len; i++) aobj->u.array.data[i] = aobj->u.array.data[i + 1]; aobj->u.array.len = new_len; return val;}
void rs_default_controller_call_pull_if_needed(ant_t *js, ant_value_t controller_obj);bool rs_default_controller_can_close_or_enqueue(rs_controller_t *ctrl, rs_stream_t *stream);
void rs_default_controller_clear_algorithms(ant_value_t ctrl_obj) { js_set_slot(ctrl_obj, SLOT_RS_PULL, js_mkundef()); js_set_slot(ctrl_obj, SLOT_RS_CANCEL, js_mkundef()); js_set_slot(ctrl_obj, SLOT_RS_SIZE, js_mkundef());}
static double rs_default_controller_get_desired_size(rs_controller_t *ctrl, rs_stream_t *stream) { if (!stream) return 0; if (stream->state == RS_STATE_ERRORED) return -1; if (stream->state == RS_STATE_CLOSED) return 0; return ctrl->strategy_hwm - ctrl->queue_total_size;}
static bool rs_default_controller_should_call_pull(ant_t *js, rs_controller_t *ctrl, rs_stream_t *stream, ant_value_t ctrl_obj) { if (!rs_default_controller_can_close_or_enqueue(ctrl, stream)) return false; if (!ctrl->started) return false;
ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) return true;
double desired = rs_default_controller_get_desired_size(ctrl, stream); return desired > 0;}
bool rs_default_controller_can_close_or_enqueue(rs_controller_t *ctrl, rs_stream_t *stream) { if (!ctrl || !stream) return false; if (ctrl->close_requested) return false; if (stream->state != RS_STATE_READABLE) return false; return true;}
void rs_fulfill_read_request(ant_t *js, ant_value_t stream_obj, ant_value_t chunk, bool done) { ant_value_t reader_obj = rs_stream_reader(stream_obj); if (!rs_is_reader(reader_obj)) return; ant_value_t promise = rs_reader_reqs_shift(js, reader_obj); if (vtype(promise) == T_UNDEF) return; ant_value_t result = js_iter_result(js, !done, chunk); js_resolve_promise(js, promise, result);}
void rs_default_reader_error_read_requests(ant_t *js, ant_value_t reader_obj, ant_value_t e) { ant_value_t arr = rs_reader_reqs(reader_obj); if (vtype(arr) != T_ARR) return; ant_offset_t len = js_arr_len(js, arr); for (ant_offset_t i = 0; i < len; i++) js_reject_promise(js, js_arr_get(js, arr, i), e); ant_object_t *aobj = js_obj_ptr(arr); aobj->u.array.len = 0;}
void readable_stream_close(ant_t *js, ant_value_t stream_obj) { rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream) return; stream->state = RS_STATE_CLOSED;
ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj)) { ant_value_t arr = rs_reader_reqs(reader_obj); if (vtype(arr) == T_ARR) { ant_offset_t len = js_arr_len(js, arr); for (ant_offset_t i = 0; i < len; i++) { ant_value_t result = js_iter_result(js, false, js_mkundef()); js_resolve_promise(js, js_arr_get(js, arr, i), result); } ant_object_t *aobj = js_obj_ptr(arr); aobj->u.array.len = 0; } js_resolve_promise(js, rs_reader_closed(reader_obj), js_mkundef()); }}
void readable_stream_error(ant_t *js, ant_value_t stream_obj, ant_value_t e) { rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream || stream->state != RS_STATE_READABLE) return; stream->state = RS_STATE_ERRORED; js_set_slot(stream_obj, SLOT_AUX, e);
ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj)) { js_reject_promise(js, rs_reader_closed(reader_obj), e); rs_default_reader_error_read_requests(js, reader_obj, e); }}
ant_value_t rs_cancel_resolve(ant_t *js, ant_value_t *args, int nargs) { ant_value_t p = js_get_slot(js->current_func, SLOT_DATA); js_resolve_promise(js, p, js_mkundef()); return js_mkundef();}
ant_value_t rs_cancel_reject(ant_t *js, ant_value_t *args, int nargs) { ant_value_t p = js_get_slot(js->current_func, SLOT_DATA); js_reject_promise(js, p, nargs > 0 ? args[0] : js_mkundef()); return js_mkundef();}
ant_value_t readable_stream_cancel(ant_t *js, ant_value_t stream_obj, ant_value_t reason) { rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream) return js_mkundef(); stream->disturbed = true;
if (stream->state == RS_STATE_CLOSED) { ant_value_t p = js_mkpromise(js); js_resolve_promise(js, p, js_mkundef()); return p; } if (stream->state == RS_STATE_ERRORED) { ant_value_t p = js_mkpromise(js); js_reject_promise(js, p, rs_stream_error(stream_obj)); return p; }
readable_stream_close(js, stream_obj);
ant_value_t ctrl_obj = rs_stream_controller(js, stream_obj); ant_value_t cancel_fn = rs_ctrl_cancel(ctrl_obj); ant_value_t result = js_mkundef(); if (is_callable(cancel_fn)) { ant_value_t cancel_args[1] = { reason }; result = sv_vm_call(js->vm, js, cancel_fn, ctrl_obj, cancel_args, 1, NULL, false); } rs_default_controller_clear_algorithms(ctrl_obj); ant_value_t p = js_mkpromise(js);
if (is_err(result)) { ant_value_t thrown = js->thrown_value; js_reject_promise(js, p, is_object_type(thrown) ? thrown : result); } else if (vtype(result) == T_PROMISE) { ant_value_t res_fn = js_heavy_mkfun(js, rs_cancel_resolve, p); ant_value_t rej_fn = js_heavy_mkfun(js, rs_cancel_reject, p); js_promise_then(js, result, res_fn, rej_fn); } else js_resolve_promise(js, p, js_mkundef());
return p;}
static ant_value_t rs_pull_resolve_handler(ant_t *js, ant_value_t *args, int nargs) { ant_value_t ctrl_obj = js_get_slot(js->current_func, SLOT_DATA); rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return js_mkundef(); ctrl->pulling = false; if (ctrl->pull_again) { ctrl->pull_again = false; rs_default_controller_call_pull_if_needed(js, ctrl_obj); } return js_mkundef();}
static ant_value_t rs_pull_reject_handler(ant_t *js, ant_value_t *args, int nargs) { ant_value_t ctrl_obj = js_get_slot(js->current_func, SLOT_DATA); rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return js_mkundef(); ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (stream && stream->state == RS_STATE_READABLE) readable_stream_error(js, stream_obj, nargs > 0 ? args[0] : js_mkundef()); return js_mkundef();}
void rs_default_controller_call_pull_if_needed(ant_t *js, ant_value_t controller_obj) { rs_controller_t *ctrl = rs_get_controller(controller_obj); if (!ctrl) return; ant_value_t stream_obj = rs_ctrl_stream(controller_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream) return;
if (!rs_default_controller_should_call_pull(js, ctrl, stream, controller_obj)) return; if (ctrl->pulling) { ctrl->pull_again = true; return; } ctrl->pulling = true;
ant_value_t pull_fn = rs_ctrl_pull(controller_obj); if (is_callable(pull_fn)) { ant_value_t args[1] = { controller_obj }; ant_value_t result = sv_vm_call(js->vm, js, pull_fn, js_mkundef(), args, 1, NULL, false);
if (vtype(result) == T_PROMISE) { ant_value_t resolve_fn = js_heavy_mkfun(js, rs_pull_resolve_handler, controller_obj); ant_value_t reject_fn = js_heavy_mkfun(js, rs_pull_reject_handler, controller_obj); js_promise_then(js, result, resolve_fn, reject_fn); } else if (is_err(result)) { if (stream->state == RS_STATE_READABLE) { ant_value_t thrown = js->thrown_value; readable_stream_error(js, stream_obj, is_object_type(thrown) ? thrown : result); } } else { ant_value_t resolved = js_mkpromise(js); js_resolve_promise(js, resolved, js_mkundef()); ant_value_t resolve_fn = js_heavy_mkfun(js, rs_pull_resolve_handler, controller_obj); ant_value_t reject_fn = js_heavy_mkfun(js, rs_pull_reject_handler, controller_obj); js_promise_then(js, resolved, resolve_fn, reject_fn); } } else ctrl->pulling = false;}
ant_value_t rs_default_reader_read(ant_t *js, ant_value_t reader_obj) { ant_value_t stream_obj = rs_reader_stream(reader_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Reader has no stream");
stream->disturbed = true;
if (stream->state == RS_STATE_CLOSED) { ant_value_t p = js_mkpromise(js); js_resolve_promise(js, p, js_iter_result(js, false, js_mkundef())); return p; } if (stream->state == RS_STATE_ERRORED) { ant_value_t p = js_mkpromise(js); js_reject_promise(js, p, rs_stream_error(stream_obj)); return p; }
ant_value_t ctrl_obj = rs_stream_controller(js, stream_obj); rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (ctrl && rs_ctrl_queue_len(js, ctrl_obj) > 0) { ant_value_t chunk = rs_ctrl_queue_shift(js, ctrl_obj); double chunk_size = 1; if (ctrl->queue_sizes_len > 0) { chunk_size = ctrl->queue_sizes[0]; ctrl->queue_sizes_len--; memmove(ctrl->queue_sizes, ctrl->queue_sizes + 1, ctrl->queue_sizes_len * sizeof(double)); } ctrl->queue_total_size -= chunk_size; if (ctrl->queue_total_size < 0) ctrl->queue_total_size = 0; bool should_close = ctrl->close_requested && rs_ctrl_queue_len(js, ctrl_obj) == 0; ant_value_t p = js_mkpromise(js); js_resolve_promise(js, p, js_iter_result(js, true, chunk)); if (should_close) { rs_default_controller_clear_algorithms(ctrl_obj); readable_stream_close(js, stream_obj); } else rs_default_controller_call_pull_if_needed(js, ctrl_obj);
return p; }
ant_value_t p = js_mkpromise(js); rs_reader_reqs_push(js, reader_obj, p); rs_default_controller_call_pull_if_needed(js, ctrl_obj); return p;}
static ant_value_t js_rs_controller_get_desired_size(ant_t *js, ant_value_t *args, int nargs) { rs_controller_t *ctrl = rs_get_controller(js->this_val); if (!ctrl) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStreamDefaultController"); ant_value_t stream_obj = rs_ctrl_stream(js->this_val); rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream || stream->state == RS_STATE_ERRORED) return js_mknull(); return js_mknum(rs_default_controller_get_desired_size(ctrl, stream));}
static ant_value_t js_rs_controller_close(ant_t *js, ant_value_t *args, int nargs) { rs_controller_t *ctrl = rs_get_controller(js->this_val); if (!ctrl) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStreamDefaultController"); ant_value_t stream_obj = rs_ctrl_stream(js->this_val); rs_stream_t *stream = rs_get_stream(stream_obj); if (!rs_default_controller_can_close_or_enqueue(ctrl, stream)) return js_mkerr_typed(js, JS_ERR_TYPE, "The stream is not in a state that permits close"); ctrl->close_requested = true; if (rs_ctrl_queue_len(js, js->this_val) == 0 && !(ctrl->in_enqueue && ctrl->defer_close)) { rs_default_controller_clear_algorithms(js->this_val); readable_stream_close(js, stream_obj); } return js_mkundef();}
static ant_value_t js_rs_controller_enqueue(ant_t *js, ant_value_t *args, int nargs) { rs_controller_t *ctrl = rs_get_controller(js->this_val); if (!ctrl) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStreamDefaultController"); ant_value_t stream_obj = rs_ctrl_stream(js->this_val); rs_stream_t *stream = rs_get_stream(stream_obj); if (!rs_default_controller_can_close_or_enqueue(ctrl, stream)) return js_mkerr_typed(js, JS_ERR_TYPE, "The stream is not in a state that permits enqueue");
ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef();
ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { rs_fulfill_read_request(js, stream_obj, chunk, false); rs_default_controller_call_pull_if_needed(js, js->this_val); return js_mkundef(); }
double chunk_size = 1; ant_value_t size_fn = rs_ctrl_size(js->this_val); ctrl->in_enqueue = true; if (is_callable(size_fn)) { ant_value_t size_args[1] = { chunk }; ant_value_t size_result = sv_vm_call(js->vm, js, size_fn, js_mkundef(), size_args, 1, NULL, false); if (is_err(size_result)) { ant_value_t thrown = js->thrown_value; ant_value_t err = is_object_type(thrown) ? thrown : size_result; if (stream && stream->state == RS_STATE_ERRORED) err = rs_stream_error(stream_obj); ctrl->in_enqueue = false; readable_stream_error(js, stream_obj, err); return js_throw(js, err); } if (vtype(size_result) == T_NUM) chunk_size = js_getnum(size_result); else chunk_size = js_to_number(js, size_result); } ctrl->in_enqueue = false;
if (chunk_size < 0 || chunk_size != chunk_size || chunk_size == (double)INFINITY) { js_mkerr_typed(js, JS_ERR_RANGE, "The return value of a queuing strategy's size function must be a finite, non-NaN, non-negative number"); ant_value_t err = is_object_type(js->thrown_value) ? js->thrown_value : js_mkundef(); readable_stream_error(js, stream_obj, err); return js_throw(js, err); }
rs_ctrl_queue_push(js, js->this_val, chunk); if (ctrl->queue_sizes_len >= ctrl->queue_sizes_cap) { uint32_t new_cap = ctrl->queue_sizes_cap ? ctrl->queue_sizes_cap * 2 : 8; double *ns = realloc(ctrl->queue_sizes, new_cap * sizeof(double)); if (ns) { ctrl->queue_sizes = ns; ctrl->queue_sizes_cap = new_cap; } } if (ctrl->queue_sizes_len < ctrl->queue_sizes_cap) ctrl->queue_sizes[ctrl->queue_sizes_len++] = chunk_size; ctrl->queue_total_size += chunk_size; rs_default_controller_call_pull_if_needed(js, js->this_val); return js_mkundef();}
static ant_value_t js_rs_controller_error(ant_t *js, ant_value_t *args, int nargs) { rs_controller_t *ctrl = rs_get_controller(js->this_val); if (!ctrl) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStreamDefaultController"); ant_value_t stream_obj = rs_ctrl_stream(js->this_val); rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream || stream->state != RS_STATE_READABLE) return js_mkundef(); ant_value_t e = (nargs > 0) ? args[0] : js_mkundef(); ctrl->queue_total_size = 0; ctrl->queue_sizes_len = 0; rs_default_controller_clear_algorithms(js->this_val); readable_stream_error(js, stream_obj, e); return js_mkundef();}
ant_value_t rs_controller_enqueue(ant_t *js, ant_value_t ctrl_obj, ant_value_t chunk) { rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return js_mkundef(); ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (!rs_default_controller_can_close_or_enqueue(ctrl, stream)) return js_mkerr_typed(js, JS_ERR_TYPE, "The stream is not in a state that permits enqueue");
ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { rs_fulfill_read_request(js, stream_obj, chunk, false); rs_default_controller_call_pull_if_needed(js, ctrl_obj); return js_mkundef(); }
double chunk_size = 1; ant_value_t size_fn = rs_ctrl_size(ctrl_obj); ctrl->in_enqueue = true; if (is_callable(size_fn)) { ant_value_t size_args[1] = { chunk }; ant_value_t size_result = sv_vm_call(js->vm, js, size_fn, js_mkundef(), size_args, 1, NULL, false); if (is_err(size_result)) { ant_value_t thrown = js->thrown_value; ant_value_t err = is_object_type(thrown) ? thrown : size_result; if (stream && stream->state == RS_STATE_ERRORED) err = rs_stream_error(stream_obj); ctrl->in_enqueue = false; js->thrown_exists = false; js->thrown_value = js_mkundef(); js->thrown_stack = js_mkundef(); readable_stream_error(js, stream_obj, err); return js_throw(js, err); } if (vtype(size_result) == T_NUM) chunk_size = js_getnum(size_result); else chunk_size = js_to_number(js, size_result); } ctrl->in_enqueue = false;
if (chunk_size < 0 || chunk_size != chunk_size || chunk_size == (double)INFINITY) { ant_value_t err = js_make_error_silent(js, JS_ERR_RANGE, "The return value of a queuing strategy's size function must be a finite, non-NaN, non-negative number"); readable_stream_error(js, stream_obj, err); return js_throw(js, err); }
rs_ctrl_queue_push(js, ctrl_obj, chunk); if (ctrl->queue_sizes_len >= ctrl->queue_sizes_cap) { uint32_t new_cap = ctrl->queue_sizes_cap ? ctrl->queue_sizes_cap * 2 : 4; double *new_sizes = realloc(ctrl->queue_sizes, new_cap * sizeof(double)); if (new_sizes) { ctrl->queue_sizes = new_sizes; ctrl->queue_sizes_cap = new_cap; } } if (ctrl->queue_sizes_len < ctrl->queue_sizes_cap) ctrl->queue_sizes[ctrl->queue_sizes_len++] = chunk_size; ctrl->queue_total_size += chunk_size; rs_default_controller_call_pull_if_needed(js, ctrl_obj); return js_mkundef();}
void rs_controller_close(ant_t *js, ant_value_t ctrl_obj) { rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return; ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (!rs_default_controller_can_close_or_enqueue(ctrl, stream)) return; ctrl->close_requested = true; if (rs_ctrl_queue_len(js, ctrl_obj) == 0 && !(ctrl->in_enqueue && ctrl->defer_close)) { rs_default_controller_clear_algorithms(ctrl_obj); readable_stream_close(js, stream_obj); }}
static ant_value_t js_rs_reader_get_closed(ant_t *js, ant_value_t *args, int nargs) { return rs_reader_closed(js->this_val);}
static ant_value_t js_rs_reader_read(ant_t *js, ant_value_t *args, int nargs) { ant_value_t stream_obj = rs_reader_stream(js->this_val); if (!rs_is_stream(stream_obj)) return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot read from a released reader"); return rs_default_reader_read(js, js->this_val);}
static ant_value_t rs_release_reader_lock(ant_t *js, ant_value_t reader_obj) { ant_value_t stream_obj = rs_reader_stream(reader_obj); if (!rs_is_stream(stream_obj)) return js_mkundef(); rs_stream_t *stream = rs_get_stream(stream_obj);
if (rs_reader_has_reqs(js, reader_obj)) { ant_value_t release_err = js_make_error_silent(js, JS_ERR_TYPE, "Reader was released"); rs_default_reader_error_read_requests(js, reader_obj, release_err); }
ant_value_t new_closed = js_mkpromise(js); ant_value_t release_err = js_make_error_silent(js, JS_ERR_TYPE, "Reader was released");
if (stream->state == RS_STATE_READABLE) { ant_value_t old_closed = rs_reader_closed(reader_obj); js_reject_promise(js, old_closed, release_err); promise_mark_handled(old_closed); }
js_reject_promise(js, new_closed, release_err); promise_mark_handled(new_closed); js_set_slot(reader_obj, SLOT_RS_CLOSED, new_closed);
js_set_slot(stream_obj, SLOT_CTOR, js_mkundef()); js_set_slot(reader_obj, SLOT_ENTRIES, js_mkundef()); return js_mkundef();}
static ant_value_t js_rs_reader_release_lock(ant_t *js, ant_value_t *args, int nargs) { return rs_release_reader_lock(js, js->this_val);}
static ant_value_t js_rs_reader_cancel(ant_t *js, ant_value_t *args, int nargs) { ant_value_t stream_obj = rs_reader_stream(js->this_val); if (!rs_is_stream(stream_obj)) { ant_value_t p = js_mkpromise(js); js_mkerr_typed(js, JS_ERR_TYPE, "Cannot cancel a released reader"); js_reject_promise(js, p, js->thrown_value); return p; } ant_value_t reason = (nargs > 0) ? args[0] : js_mkundef(); return readable_stream_cancel(js, stream_obj, reason);}
ant_value_t js_rs_reader_ctor(ant_t *js, ant_value_t *args, int nargs) { if (vtype(js->new_target) == T_UNDEF) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader constructor requires 'new'"); if (nargs < 1) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader requires a stream argument");
ant_value_t stream_obj = args[0]; if (!rs_is_stream(stream_obj)) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader argument must be a ReadableStream"); rs_stream_t *stream = rs_get_stream(stream_obj); if (rs_is_reader(rs_stream_reader(stream_obj))) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked to a reader");
ant_value_t closed = js_mkpromise(js); promise_mark_handled(closed); ant_value_t obj = js_mkobj(js); ant_value_t proto = js_instance_proto_from_new_target(js, g_reader_proto); if (is_object_type(proto)) js_set_proto_init(obj, proto); js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM_READER)); js_set_slot(obj, SLOT_ENTRIES, stream_obj); js_set_slot(obj, SLOT_RS_CLOSED, closed); js_set_slot(obj, SLOT_AUX, js_mkarr(js)); js_set_slot(stream_obj, SLOT_CTOR, obj);
if (stream->state == RS_STATE_CLOSED) js_resolve_promise(js, closed, js_mkundef()); else if (stream->state == RS_STATE_ERRORED) js_reject_promise(js, closed, rs_stream_error(stream_obj));
return obj;}
static ant_value_t js_rs_get_locked(ant_t *js, ant_value_t *args, int nargs) { rs_stream_t *stream = rs_get_stream(js->this_val); if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); return js_bool(rs_is_reader(rs_stream_reader(js->this_val)));}
static ant_value_t js_rs_cancel(ant_t *js, ant_value_t *args, int nargs) { rs_stream_t *stream = rs_get_stream(js->this_val); if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); if (rs_is_reader(rs_stream_reader(js->this_val))) { ant_value_t p = js_mkpromise(js); js_mkerr_typed(js, JS_ERR_TYPE, "Cannot cancel a locked ReadableStream"); js_reject_promise(js, p, js->thrown_value); return p; } ant_value_t reason = (nargs > 0) ? args[0] : js_mkundef(); return readable_stream_cancel(js, js->this_val, reason);}
static ant_value_t js_rs_get_reader(ant_t *js, ant_value_t *args, int nargs) { rs_stream_t *stream = rs_get_stream(js->this_val); if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream");
if (nargs > 0 && is_object_type(args[0])) { ant_value_t mode = js_get(js, args[0], "mode"); if (!is_undefined(mode)) { ant_value_t mode_str_v = mode; if (vtype(mode) != T_STR) { mode_str_v = js_tostring_val(js, mode); if (is_err(mode_str_v)) return mode_str_v; } size_t mode_len; const char *mode_str = js_getstr(js, mode_str_v, &mode_len); if (mode_str && mode_len == 4 && memcmp(mode_str, "byob", 4) == 0) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamBYOBReader is not yet implemented"); return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid reader mode"); } }
ant_value_t reader_args[1] = { js->this_val }; ant_value_t saved_new_target = js->new_target; js->new_target = g_reader_proto; ant_value_t reader = js_rs_reader_ctor(js, reader_args, 1); js->new_target = saved_new_target; return reader;}
static ant_value_t js_rs_async_iter_next(ant_t *js, ant_value_t *args, int nargs) { ant_value_t reader = js_get_slot(js->this_val, SLOT_DATA); if (!rs_is_reader(reader)) return js_mkerr_typed( js, JS_ERR_TYPE, "ReadableStream async iterator has no reader" ); return rs_default_reader_read(js, reader);}
static ant_value_t js_rs_async_iter_return(ant_t *js, ant_value_t *args, int nargs) { ant_value_t reader = js_get_slot(js->this_val, SLOT_DATA); if (!rs_is_reader(reader)) { ant_value_t p = js_mkpromise(js); js_resolve_promise(js, p, js_iter_result(js, false, js_mkundef())); return p; }
ant_value_t stream_obj = rs_reader_stream(reader); ant_value_t reason = (nargs > 0) ? args[0] : js_mkundef(); readable_stream_cancel(js, stream_obj, reason); rs_release_reader_lock(js, reader);
ant_value_t p = js_mkpromise(js); js_resolve_promise(js, p, js_iter_result(js, false, js_mkundef())); return p;}
static ant_value_t js_rs_values(ant_t *js, ant_value_t *args, int nargs) { ant_value_t reader = js_rs_get_reader(js, NULL, 0); if (is_err(reader)) return reader;
ant_value_t iterator = js_mkobj(js); js_set_proto_init(iterator, g_rs_async_iter_proto); js_set_slot(iterator, SLOT_DATA, reader); return iterator;}
static ant_value_t rs_start_resolve_handler(ant_t *js, ant_value_t *args, int nargs) { ant_value_t ctrl_obj = js_get_slot(js->current_func, SLOT_DATA); rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return js_mkundef(); ctrl->started = true; ctrl->pulling = false; ctrl->pull_again = false; rs_default_controller_call_pull_if_needed(js, ctrl_obj); return js_mkundef();}
static ant_value_t rs_start_reject_handler(ant_t *js, ant_value_t *args, int nargs) { ant_value_t ctrl_obj = js_get_slot(js->current_func, SLOT_DATA); rs_controller_t *ctrl = rs_get_controller(ctrl_obj); if (!ctrl) return js_mkundef(); ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); rs_stream_t *stream = rs_get_stream(stream_obj); if (stream && stream->state == RS_STATE_READABLE) readable_stream_error( js, stream_obj, nargs > 0 ? args[0] : js_mkundef() ); return js_mkundef();}
static ant_value_t setup_default_controller( ant_t *js, ant_value_t stream_obj, ant_value_t pull_fn, ant_value_t cancel_fn, ant_value_t size_fn, double hwm) { rs_controller_t *ctrl = calloc(1, sizeof(rs_controller_t)); if (!ctrl) return js_mkerr(js, "out of memory"); ctrl->strategy_hwm = hwm;
ant_value_t ctrl_obj = js_mkobj(js); js_set_proto_init(ctrl_obj, g_controller_proto); js_set_slot(ctrl_obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM_CONTROLLER)); js_set_slot(ctrl_obj, SLOT_DATA, ANT_PTR(ctrl)); js_set_slot(ctrl_obj, SLOT_ENTRIES, stream_obj); js_set_slot(ctrl_obj, SLOT_RS_PULL, pull_fn); js_set_slot(ctrl_obj, SLOT_RS_CANCEL, cancel_fn); js_set_slot(ctrl_obj, SLOT_RS_SIZE, size_fn); js_set_slot(ctrl_obj, SLOT_AUX, js_mkarr(js)); js_set_finalizer(ctrl_obj, rs_controller_finalize);
js_set_slot(stream_obj, SLOT_ENTRIES, ctrl_obj); return ctrl_obj;}
static ant_value_t js_rs_ctor(ant_t *js, ant_value_t *args, int nargs) { if (vtype(js->new_target) == T_UNDEF) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream constructor requires 'new'");
ant_value_t underlying_source = js_mkundef(); bool is_bytes_source = false; if (nargs > 0 && !is_undefined(args[0])) { if (is_null(args[0])) return js_mkerr_typed(js, JS_ERR_TYPE, "The underlying source cannot be null"); underlying_source = args[0]; }
if (is_object_type(underlying_source)) { ant_value_t type_val = js_get(js, underlying_source, "type"); if (!is_undefined(type_val)) { ant_value_t coerced = type_val; if (vtype(type_val) != T_STR) { coerced = js_tostring_val(js, type_val); if (is_err(coerced)) return coerced; } size_t tlen; const char *tstr = js_getstr(js, coerced, &tlen); if (tstr && tlen == 5 && memcmp(tstr, "bytes", 5) == 0) { // TODO: accept byte sources, but currently back them with the default // controller path until BYOB readers/controllers are implemented is_bytes_source = true; } else return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid type is specified"); }}
ant_value_t strategy = js_mkundef(); if (nargs > 1 && !is_undefined(args[1]) && !is_null(args[1])) strategy = args[1];
double hwm = 1; if (is_object_type(strategy)) { ant_value_t hwm_val = js_get(js, strategy, "highWaterMark"); if (is_err(hwm_val)) return hwm_val; if (!is_undefined(hwm_val)) { hwm = js_to_number(js, hwm_val); if (hwm != hwm || hwm < 0) return js_mkerr_typed(js, JS_ERR_RANGE, "Invalid highWaterMark"); } }
ant_value_t size_fn = js_mkundef(); if (is_object_type(strategy)) { ant_value_t s = js_get(js, strategy, "size"); if (is_err(s)) return s; if (!is_undefined(s)) { if (!is_callable(s)) return js_mkerr_typed(js, JS_ERR_TYPE, "size must be a function"); size_fn = s; } }
rs_stream_t *st = calloc(1, sizeof(rs_stream_t)); if (!st) return js_mkerr(js, "out of memory"); st->state = RS_STATE_READABLE;
ant_value_t obj = js_mkobj(js); ant_value_t proto = js_instance_proto_from_new_target(js, g_rs_proto); if (is_object_type(proto)) js_set_proto_init(obj, proto); js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM)); js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); js_set_finalizer(obj, rs_stream_finalize);
if (is_bytes_source) js_set(js, obj, "supportsBYOB", js_false);
ant_value_t pull_fn = js_mkundef(); ant_value_t cancel_fn = js_mkundef(); ant_value_t start_fn = js_mkundef();
if (is_object_type(underlying_source)) { ant_value_t pv = js_get(js, underlying_source, "pull"); if (is_err(pv)) return pv; if (!is_undefined(pv)) { if (!is_callable(pv)) return js_mkerr_typed(js, JS_ERR_TYPE, "pull must be a function"); pull_fn = pv; } ant_value_t cv = js_get(js, underlying_source, "cancel"); if (is_err(cv)) return cv; if (!is_undefined(cv)) { if (!is_callable(cv)) return js_mkerr_typed(js, JS_ERR_TYPE, "cancel must be a function"); cancel_fn = cv; } ant_value_t sv = js_get(js, underlying_source, "start"); if (is_err(sv)) return sv; if (!is_undefined(sv)) { if (!is_callable(sv)) return js_mkerr_typed(js, JS_ERR_TYPE, "start must be a function"); start_fn = sv; } }
ant_value_t ctrl_obj = setup_default_controller(js, obj, pull_fn, cancel_fn, size_fn, hwm); if (is_err(ctrl_obj)) return ctrl_obj;
if (is_callable(start_fn)) { ant_value_t start_args[1] = { ctrl_obj }; ant_value_t start_result = sv_vm_call(js->vm, js, start_fn, underlying_source, start_args, 1, NULL, false); if (is_err(start_result)) return start_result;
if (vtype(start_result) == T_PROMISE) { ant_value_t resolve_fn = js_heavy_mkfun(js, rs_start_resolve_handler, ctrl_obj); ant_value_t reject_fn = js_heavy_mkfun(js, rs_start_reject_handler, ctrl_obj); js_promise_then(js, start_result, resolve_fn, reject_fn); }
if (vtype(start_result) != T_PROMISE) { ant_value_t resolved = js_mkpromise(js); js_resolve_promise(js, resolved, js_mkundef()); ant_value_t res_fn = js_heavy_mkfun(js, rs_start_resolve_handler, ctrl_obj); ant_value_t rej_fn = js_heavy_mkfun(js, rs_start_reject_handler, ctrl_obj); js_promise_then(js, resolved, res_fn, rej_fn); } } else { ant_value_t resolved = js_mkpromise(js); js_resolve_promise(js, resolved, js_mkundef()); ant_value_t res_fn = js_heavy_mkfun(js, rs_start_resolve_handler, ctrl_obj); ant_value_t rej_fn = js_heavy_mkfun(js, rs_start_reject_handler, ctrl_obj); js_promise_then(js, resolved, res_fn, rej_fn); }
return obj;}
ant_value_t rs_create_stream(ant_t *js, ant_value_t pull_fn, ant_value_t cancel_fn, double hwm) { rs_stream_t *st = calloc(1, sizeof(rs_stream_t)); if (!st) return js_mkerr(js, "out of memory"); st->state = RS_STATE_READABLE;
ant_value_t obj = js_mkobj(js); js_set_proto_init(obj, g_rs_proto); js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM)); js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); js_set_finalizer(obj, rs_stream_finalize);
ant_value_t ctrl_obj = setup_default_controller(js, obj, pull_fn, cancel_fn, js_mkundef(), hwm); if (is_err(ctrl_obj)) return ctrl_obj;
ant_value_t resolved = js_mkpromise(js); js_resolve_promise(js, resolved, js_mkundef()); ant_value_t res_fn = js_heavy_mkfun(js, rs_start_resolve_handler, ctrl_obj); ant_value_t rej_fn = js_heavy_mkfun(js, rs_start_reject_handler, ctrl_obj); js_promise_then(js, resolved, res_fn, rej_fn);
return obj;}
static ant_value_t js_rs_controller_ctor(ant_t *js, ant_value_t *args, int nargs) { return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultController cannot be constructed directly");}
void gc_mark_readable_streams(ant_t *js, void (*mark)(ant_t *, ant_value_t)) { mark(js, g_rs_proto); mark(js, g_reader_proto); mark(js, g_controller_proto); mark(js, g_rs_async_iter_proto);}
void init_readable_stream_module(void) { ant_t *js = rt->js; ant_value_t g = js_glob(js);
g_controller_proto = js_mkobj(js); js_set_getter_desc(js, g_controller_proto, "desiredSize", 11, js_mkfun(js_rs_controller_get_desired_size), JS_DESC_C); js_set(js, g_controller_proto, "close", js_mkfun(js_rs_controller_close)); js_set_descriptor(js, g_controller_proto, "close", 5, JS_DESC_W | JS_DESC_C); js_set(js, g_controller_proto, "enqueue", js_mkfun(js_rs_controller_enqueue)); js_set_descriptor(js, g_controller_proto, "enqueue", 7, JS_DESC_W | JS_DESC_C); js_set(js, g_controller_proto, "error", js_mkfun(js_rs_controller_error)); js_set_descriptor(js, g_controller_proto, "error", 5, JS_DESC_W | JS_DESC_C); js_set_sym(js, g_controller_proto, get_toStringTag_sym(), js_mkstr(js, "ReadableStreamDefaultController", 31));
ant_value_t ctrl_ctor = js_make_ctor(js, js_rs_controller_ctor, g_controller_proto, "ReadableStreamDefaultController", 31); js_set(js, g, "ReadableStreamDefaultController", ctrl_ctor); js_set_descriptor(js, g, "ReadableStreamDefaultController", 31, JS_DESC_W | JS_DESC_C);
g_reader_proto = js_mkobj(js); js_set_getter_desc(js, g_reader_proto, "closed", 6, js_mkfun(js_rs_reader_get_closed), JS_DESC_C); js_set(js, g_reader_proto, "read", js_mkfun(js_rs_reader_read)); js_set_descriptor(js, g_reader_proto, "read", 4, JS_DESC_W | JS_DESC_C); js_set(js, g_reader_proto, "releaseLock", js_mkfun(js_rs_reader_release_lock)); js_set_descriptor(js, g_reader_proto, "releaseLock", 11, JS_DESC_W | JS_DESC_C); js_set(js, g_reader_proto, "cancel", js_mkfun(js_rs_reader_cancel)); js_set_descriptor(js, g_reader_proto, "cancel", 6, JS_DESC_W | JS_DESC_C); js_set_sym(js, g_reader_proto, get_toStringTag_sym(), js_mkstr(js, "ReadableStreamDefaultReader", 27));
ant_value_t reader_ctor = js_make_ctor(js, js_rs_reader_ctor, g_reader_proto, "ReadableStreamDefaultReader", 27); js_set(js, g, "ReadableStreamDefaultReader", reader_ctor); js_set_descriptor(js, g, "ReadableStreamDefaultReader", 27, JS_DESC_W | JS_DESC_C);
g_rs_async_iter_proto = js_mkobj(js); js_set(js, g_rs_async_iter_proto, "next", js_mkfun(js_rs_async_iter_next)); js_set_descriptor(js, g_rs_async_iter_proto, "next", 4, JS_DESC_W | JS_DESC_C); js_set(js, g_rs_async_iter_proto, "return", js_mkfun(js_rs_async_iter_return)); js_set_descriptor(js, g_rs_async_iter_proto, "return", 6, JS_DESC_W | JS_DESC_C); js_set_sym(js, g_rs_async_iter_proto, get_asyncIterator_sym(), js_mkfun(sym_this_cb));
g_rs_proto = js_mkobj(js); js_set_getter_desc(js, g_rs_proto, "locked", 6, js_mkfun(js_rs_get_locked), JS_DESC_C); js_set(js, g_rs_proto, "cancel", js_mkfun(js_rs_cancel)); js_set_descriptor(js, g_rs_proto, "cancel", 6, JS_DESC_W | JS_DESC_C); js_set(js, g_rs_proto, "getReader", js_mkfun(js_rs_get_reader)); js_set_descriptor(js, g_rs_proto, "getReader", 9, JS_DESC_W | JS_DESC_C); init_pipes_proto(js, g_rs_proto); js_set(js, g_rs_proto, "values", js_mkfun(js_rs_values)); js_set_descriptor(js, g_rs_proto, "values", 6, JS_DESC_W | JS_DESC_C); js_set_sym(js, g_rs_proto, get_asyncIterator_sym(), js_get(js, g_rs_proto, "values")); js_set_sym(js, g_rs_proto, get_toStringTag_sym(), js_mkstr(js, "ReadableStream", 14));
ant_value_t rs_ctor = js_make_ctor(js, js_rs_ctor, g_rs_proto, "ReadableStream", 14); js_set(js, g, "ReadableStream", rs_ctor); js_set_descriptor(js, g, "ReadableStream", 14, JS_DESC_W | JS_DESC_C);}