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.

remove duck-typing from streams

+222 -198
+1
include/modules/abort.h
··· 10 10 void signal_do_abort(ant_t *js, ant_value_t signal, ant_value_t reason); 11 11 void abort_signal_add_listener(ant_t *js, ant_value_t signal, ant_value_t callback); 12 12 13 + bool abort_signal_is_signal(ant_value_t signal); 13 14 bool abort_signal_is_aborted(ant_value_t signal); 14 15 ant_value_t abort_signal_get_reason(ant_value_t signal); 15 16
+4
include/streams/readable.h
··· 38 38 void init_readable_stream_module(void); 39 39 void gc_mark_readable_streams(ant_t *js, void (*mark)(ant_t *, ant_value_t)); 40 40 41 + bool rs_is_stream(ant_value_t obj); 42 + bool rs_is_reader(ant_value_t obj); 43 + bool rs_is_controller(ant_value_t obj); 44 + 41 45 rs_stream_t *rs_get_stream(ant_value_t obj); 42 46 rs_controller_t *rs_get_controller(ant_value_t obj); 43 47 ant_offset_t rs_ctrl_queue_len(ant_t *js, ant_value_t ctrl_obj);
+6
include/streams/transform.h
··· 7 7 void init_transform_stream_module(void); 8 8 void gc_mark_transform_streams(ant_t *js, void (*mark)(ant_t *, ant_value_t)); 9 9 10 + bool ts_is_stream(ant_value_t obj); 11 + bool ts_is_controller(ant_value_t obj); 12 + 13 + ant_value_t ts_stream_readable(ant_value_t ts_obj); 14 + ant_value_t ts_stream_writable(ant_value_t ts_obj); 15 + 10 16 #endif
+4
include/streams/writable.h
··· 36 36 void init_writable_stream_module(void); 37 37 void gc_mark_writable_streams(ant_t *js, void (*mark)(ant_t *, ant_value_t)); 38 38 39 + bool ws_is_stream(ant_value_t obj); 40 + bool ws_is_writer(ant_value_t obj); 41 + bool ws_is_controller(ant_value_t obj); 42 + 39 43 ws_stream_t *ws_get_stream(ant_value_t obj); 40 44 ws_controller_t *ws_get_controller(ant_value_t obj); 41 45
+13 -16
src/ant.c
··· 623 623 624 624 bool js_truthy(ant_t *js, ant_value_t v) { 625 625 static const void *dispatch[] = { 626 - [T_OBJ] = &&l_true, 627 - [T_FUNC] = &&l_true, 628 - [T_CFUNC] = &&l_true, 629 - [T_ARR] = &&l_true, 630 - [T_SYMBOL] = &&l_true, 631 - [T_BOOL] = &&l_bool, 632 - [T_STR] = &&l_str, 633 - [T_BIGINT] = &&l_bigint, 634 - [T_NUM] = &&l_num, 626 + [T_OBJ] = &&l_true, 627 + [T_FUNC] = &&l_true, 628 + [T_CFUNC] = &&l_true, 629 + [T_ARR] = &&l_true, 630 + [T_PROMISE] = &&l_true, 631 + [T_SYMBOL] = &&l_true, 632 + [T_BOOL] = &&l_bool, 633 + [T_STR] = &&l_str, 634 + [T_BIGINT] = &&l_bigint, 635 + [T_NUM] = &&l_num, 635 636 }; 636 637 637 638 uint8_t t = vtype(v); ··· 5644 5645 if (has_get) js_set_sym_getter_desc(js, as_obj, prop, getter, desc_flags); 5645 5646 if (has_set) js_set_sym_setter_desc(js, as_obj, prop, setter, desc_flags); 5646 5647 } else { 5647 - if (has_get && has_set) { 5648 - js_set_accessor_desc(js, as_obj, prop_str, prop_len, getter, setter, desc_flags); 5649 - } else if (has_get) { 5650 - js_set_getter_desc(js, as_obj, prop_str, prop_len, getter, desc_flags); 5651 - } else { 5652 - js_set_setter_desc(js, as_obj, prop_str, prop_len, setter, desc_flags); 5653 - } 5648 + if (has_get && has_set) js_set_accessor_desc(js, as_obj, prop_str, prop_len, getter, setter, desc_flags); 5649 + else if (has_get) js_set_getter_desc(js, as_obj, prop_str, prop_len, getter, desc_flags); 5650 + else js_set_setter_desc(js, as_obj, prop_str, prop_len, setter, desc_flags); 5654 5651 } 5655 5652 } else { 5656 5653 int desc_flags =
+4
src/modules/abort.c
··· 395 395 return data && data->aborted; 396 396 } 397 397 398 + bool abort_signal_is_signal(ant_value_t signal) { 399 + return get_signal_data(signal) != NULL; 400 + } 401 + 398 402 ant_value_t abort_signal_get_reason(ant_value_t signal) { 399 403 abort_signal_data_t *data = get_signal_data(signal); 400 404 return data ? data->reason : js_mkundef();
+2 -2
src/modules/headers.c
··· 585 585 js_set(js, g_headers_proto, "getSetCookie", js_mkfun(js_headers_get_set_cookie)); 586 586 587 587 js_set_sym(js, g_headers_proto, get_iterator_sym(), js_mkfun(js_headers_symbol_iterator)); 588 - js_set_sym_getter_desc(js, g_headers_proto, get_toStringTag_sym(), js_mkfun(sym_this_cb), 0); 588 + js_set_sym(js, g_headers_proto, get_toStringTag_sym(), js_mkstr(js, "Headers", 7)); 589 589 590 590 ant_value_t ctor_obj = js_mkobj(js); 591 591 js_set_slot(ctor_obj, SLOT_CFUNC, js_mkfun(js_headers_ctor)); 592 592 js_mkprop_fast(js, ctor_obj, "prototype", 9, g_headers_proto); 593 - js_mkprop_fast(js, ctor_obj, "name", 4, js_mkstr(js, "Headers", 7)); 593 + js_mkprop_fast(js, ctor_obj, "name", 4, js_mkstr(js, "Headers", 7)); 594 594 js_set_descriptor(js, ctor_obj, "name", 4, 0); 595 595 596 596 ant_value_t ctor = js_obj_to_func(ctor_obj);
+43 -44
src/streams/pipes.c
··· 12 12 #include "streams/readable.h" 13 13 #include "streams/writable.h" 14 14 15 - static void pipes_chain_thenable( 15 + static void pipes_chain_promise( 16 16 ant_t *js, ant_value_t value, 17 17 ant_value_t on_resolve, ant_value_t on_reject 18 18 ) { 19 - ant_value_t thenable = value; 20 - if (vtype(thenable) != T_PROMISE) { 21 - thenable = js_mkpromise(js); 22 - js_resolve_promise(js, thenable, value); 19 + ant_value_t promise = value; 20 + if (vtype(promise) != T_PROMISE) { 21 + promise = js_mkpromise(js); 22 + js_resolve_promise(js, promise, value); 23 23 } 24 24 25 - ant_value_t then_fn = js_get(js, thenable, "then"); 25 + ant_value_t then_fn = js_get(js, promise, "then"); 26 26 if (!is_callable(then_fn)) return; 27 27 28 28 ant_value_t then_args[2] = { on_resolve, on_reject }; 29 - sv_vm_call(js->vm, js, then_fn, thenable, then_args, 2, NULL, false); 29 + sv_vm_call(js->vm, js, then_fn, promise, then_args, 2, NULL, false); 30 30 } 31 31 32 32 typedef struct { ··· 76 76 77 77 static void pipes_release_reader(ant_t *js, ant_value_t reader_obj) { 78 78 ant_value_t stream_obj = rs_reader_stream(reader_obj); 79 - if (!is_object_type(stream_obj)) return; 79 + if (!rs_is_stream(stream_obj)) return; 80 80 81 81 if (rs_reader_has_reqs(js, reader_obj)) { 82 82 ant_value_t release_err = js_make_error_silent(js, JS_ERR_TYPE, "Reader was released"); ··· 103 103 104 104 static void pipes_release_writer(ant_t *js, ant_value_t writer_obj) { 105 105 ant_value_t ws_obj = js_get_slot(writer_obj, SLOT_ENTRIES); 106 - if (!is_object_type(ws_obj)) return; 106 + if (!ws_is_stream(ws_obj)) return; 107 107 108 108 ant_value_t rel_err = js_make_error_silent(js, JS_ERR_TYPE, "Writer was released"); 109 109 ant_value_t ready = js_mkpromise(js); ··· 122 122 123 123 static void pipes_release_locks(ant_t *js, ant_value_t state) { 124 124 ant_value_t reader = pipe_state_reader(state); 125 - if (is_object_type(reader)) { 125 + if (rs_is_reader(reader)) { 126 126 pipes_release_reader(js, reader); 127 127 js_set_slot(state, SLOT_BUFFER, js_mkundef()); 128 128 } 129 129 130 130 ant_value_t writer = pipe_state_writer(state); 131 - if (is_object_type(writer)) { 131 + if (ws_is_writer(writer)) { 132 132 pipes_release_writer(js, writer); 133 133 js_set_slot(state, SLOT_DEFAULT, js_mkundef()); 134 134 } ··· 230 230 return js_mkundef(); 231 231 } 232 232 233 + static ant_value_t pipe_ignore(ant_t *js, ant_value_t *args, int nargs) { 234 + return js_mkundef(); 235 + } 236 + 233 237 static ant_value_t pipe_read_resolve(ant_t *js, ant_value_t *args, int nargs) { 234 238 ant_value_t state = js_get_slot(js->current_func, SLOT_DATA); 235 239 pipe_state_t *pst = pipe_get_state(state); ··· 251 255 ant_value_t close_promise = writable_stream_close(js, pipe_state_dest(state)); 252 256 ant_value_t on_resolve = js_heavy_mkfun(js, pipe_close_dest_resolve, state); 253 257 ant_value_t on_reject = js_heavy_mkfun(js, pipe_close_dest_reject, state); 254 - pipes_chain_thenable(js, close_promise, on_resolve, on_reject); 258 + pipes_chain_promise(js, close_promise, on_resolve, on_reject); 255 259 return js_mkundef(); 256 260 } 257 261 ··· 259 263 ant_value_t write_promise = ws_writer_write(js, pipe_state_writer(state), value); 260 264 ant_value_t on_resolve = js_heavy_mkfun(js, pipe_write_resolve, state); 261 265 ant_value_t on_reject = js_heavy_mkfun(js, pipe_dest_error, state); 262 - pipes_chain_thenable(js, write_promise, on_resolve, on_reject); 266 + pipes_chain_promise(js, write_promise, on_resolve, on_reject); 263 267 return js_mkundef(); 264 268 } 265 269 ··· 281 285 ant_value_t read_promise = rs_default_reader_read(js, pipe_state_reader(state)); 282 286 ant_value_t on_resolve = js_heavy_mkfun(js, pipe_read_resolve, state); 283 287 ant_value_t on_reject = js_heavy_mkfun(js, pipe_source_error, state); 284 - pipes_chain_thenable(js, read_promise, on_resolve, on_reject); 288 + pipes_chain_promise(js, read_promise, on_resolve, on_reject); 285 289 return js_mkundef(); 286 290 } 287 291 ··· 306 310 ant_value_t ready = ws_writer_ready(writer); 307 311 ant_value_t on_resolve = js_heavy_mkfun(js, pipe_ready_resolve, state); 308 312 ant_value_t on_reject = js_heavy_mkfun(js, pipe_dest_error, state); 309 - pipes_chain_thenable(js, ready, on_resolve, on_reject); 313 + pipes_chain_promise(js, ready, on_resolve, on_reject); 310 314 } 311 315 312 316 static ant_value_t pipe_create_rejected(ant_t *js, ant_value_t error) { ··· 345 349 return pipe_create_rejected(js, js->thrown_value); 346 350 } 347 351 348 - if (is_object_type(rs_stream_reader(source))) { 352 + if (rs_is_reader(rs_stream_reader(source))) { 349 353 js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked"); 350 354 return pipe_create_rejected(js, js->thrown_value); 351 355 } 352 - if (is_object_type(ws_stream_writer(dest))) { 356 + if (ws_is_writer(ws_stream_writer(dest))) { 353 357 js_mkerr_typed(js, JS_ERR_TYPE, "WritableStream is already locked"); 354 358 return pipe_create_rejected(js, js->thrown_value); 355 359 } 356 360 357 - if (!is_undefined(signal) && !is_object_type(signal)) { 361 + if (!is_undefined(signal) && !abort_signal_is_signal(signal)) { 358 362 js_mkerr_typed(js, JS_ERR_TYPE, "pipeTo option 'signal' must be an AbortSignal"); 359 363 return pipe_create_rejected(js, js->thrown_value); 360 364 } ··· 393 397 promise_mark_handled(js_get_slot(writer, SLOT_RS_CLOSED)); 394 398 promise_mark_handled(js_get_slot(writer, SLOT_WS_READY)); 395 399 396 - if (is_object_type(signal) && abort_signal_is_aborted(signal)) { 400 + ant_value_t ignore_fn = js_heavy_mkfun(js, pipe_ignore, state); 401 + ant_value_t source_closed_reject = js_heavy_mkfun(js, pipe_source_error, state); 402 + ant_value_t dest_closed_reject = js_heavy_mkfun(js, pipe_dest_error, state); 403 + pipes_chain_promise(js, rs_reader_closed(reader), ignore_fn, source_closed_reject); 404 + pipes_chain_promise(js, js_get_slot(writer, SLOT_RS_CLOSED), ignore_fn, dest_closed_reject); 405 + 406 + if (abort_signal_is_signal(signal) && abort_signal_is_aborted(signal)) { 397 407 pipes_shutdown_from_abort(js, state, abort_signal_get_reason(signal)); 398 408 return promise; 399 409 } 400 410 401 - if (is_object_type(signal)) { 411 + if (abort_signal_is_signal(signal)) { 402 412 ant_value_t listener = js_heavy_mkfun(js, pipe_abort_listener, state); 403 413 abort_signal_add_listener(js, signal, listener); 404 414 } ··· 408 418 } 409 419 410 420 static ant_value_t js_rs_pipe_to(ant_t *js, ant_value_t *args, int nargs) { 411 - if (!is_object_type(js->this_val)) { 412 - js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 413 - return pipe_create_rejected(js, js->thrown_value); 414 - } 415 - 416 - rs_stream_t *stream = rs_get_stream(js->this_val); 417 - if (!stream) { 421 + if (!rs_is_stream(js->this_val)) { 418 422 js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 419 423 return pipe_create_rejected(js, js->thrown_value); 420 424 } ··· 430 434 431 435 static ant_value_t js_rs_pipe_through(ant_t *js, ant_value_t *args, int nargs) { 432 436 ant_value_t source = js->this_val; 433 - if (!is_object_type(source)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 434 - rs_stream_t *stream = rs_get_stream(source); 435 - 436 - if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 437 - if (is_object_type(rs_stream_reader(source))) 437 + if (!rs_is_stream(source)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 438 + if (rs_is_reader(rs_stream_reader(source))) 438 439 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked"); 439 440 if (nargs < 1 || !is_object_type(args[0])) 440 441 return js_mkerr_typed(js, JS_ERR_TYPE, "pipeThrough requires a transform object"); ··· 443 444 ant_value_t writable = js_get(js, transform, "writable"); 444 445 ant_value_t readable = js_get(js, transform, "readable"); 445 446 446 - if (!is_object_type(writable) || !ws_get_stream(writable)) 447 + if (!ws_is_stream(writable)) 447 448 return js_mkerr_typed(js, JS_ERR_TYPE, "pipeThrough transform.writable must be a WritableStream"); 448 - if (!is_object_type(readable) || !rs_get_stream(readable)) 449 + if (!rs_is_stream(readable)) 449 450 return js_mkerr_typed(js, JS_ERR_TYPE, "pipeThrough transform.readable must be a ReadableStream"); 450 - if (is_object_type(ws_stream_writer(writable))) 451 + if (ws_is_writer(ws_stream_writer(writable))) 451 452 return js_mkerr_typed(js, JS_ERR_TYPE, "WritableStream is already locked"); 452 453 453 454 bool prevent_close, prevent_abort, prevent_cancel; ··· 496 497 497 498 static void tee_release_reader(ant_t *js, ant_value_t state) { 498 499 ant_value_t reader = tee_state_reader(state); 499 - if (!is_object_type(reader)) return; 500 + if (!rs_is_reader(reader)) return; 500 501 pipes_release_reader(js, reader); 501 502 js_set_slot(state, SLOT_BUFFER, js_mkundef()); 502 503 } ··· 552 553 return; 553 554 554 555 ant_value_t r = rs_stream_reader(branch_stream); 555 - if (is_object_type(r) && rs_reader_has_reqs(js, r)) { 556 + if (rs_is_reader(r) && rs_reader_has_reqs(js, r)) { 556 557 rs_fulfill_read_request(js, branch_stream, value, false); 557 558 rs_default_controller_call_pull_if_needed(js, ctrl); 558 559 return; ··· 654 655 ant_value_t read_promise = rs_default_reader_read(js, tee_state_reader(state)); 655 656 ant_value_t on_resolve = js_heavy_mkfun(js, tee_read_resolve, state); 656 657 ant_value_t on_reject = js_heavy_mkfun(js, tee_read_reject, state); 657 - pipes_chain_thenable(js, read_promise, on_resolve, on_reject); 658 + pipes_chain_promise(js, read_promise, on_resolve, on_reject); 658 659 } 659 660 660 661 static ant_value_t tee_branch_pull(ant_t *js, ant_value_t *args, int nargs) { ··· 711 712 ant_value_t cancel_promise = readable_stream_cancel(js, orig_stream, reasons); 712 713 ant_value_t on_resolve = js_heavy_mkfun(js, tee_cancel_both_resolve, state); 713 714 ant_value_t on_reject = js_heavy_mkfun(js, tee_cancel_both_reject, state); 714 - pipes_chain_thenable(js, cancel_promise, on_resolve, on_reject); 715 + pipes_chain_promise(js, cancel_promise, on_resolve, on_reject); 715 716 } 716 717 717 718 return promise; 718 719 } 719 720 720 721 static ant_value_t js_rs_tee(ant_t *js, ant_value_t *args, int nargs) { 721 - if (!is_object_type(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 722 - rs_stream_t *stream = rs_get_stream(js->this_val); 723 - 724 - if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 725 - if (is_object_type(rs_stream_reader(js->this_val))) 722 + if (!rs_is_stream(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 723 + if (rs_is_reader(rs_stream_reader(js->this_val))) 726 724 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked"); 727 725 728 726 ant_value_t reader_args[1] = { js->this_val }; 729 727 ant_value_t saved = js->new_target; 730 728 js->new_target = g_reader_proto; 729 + 731 730 ant_value_t reader = js_rs_reader_ctor(js, reader_args, 1); 732 731 js->new_target = saved; 733 732 if (is_err(reader)) return reader;
+30 -15
src/streams/readable.c
··· 17 17 ant_value_t g_reader_proto; 18 18 ant_value_t g_controller_proto; 19 19 20 + bool rs_is_stream(ant_value_t obj) { 21 + return is_object_type(obj) && rs_get_stream(obj) != NULL; 22 + } 23 + 24 + bool rs_is_reader(ant_value_t obj) { 25 + return is_object_type(obj) 26 + && vtype(js_get_slot(obj, SLOT_RS_CLOSED)) == T_PROMISE 27 + && vtype(js_get_slot(obj, SLOT_BUFFER)) == T_ARR; 28 + } 29 + 30 + bool rs_is_controller(ant_value_t obj) { 31 + return is_object_type(obj) 32 + && rs_get_controller(obj) != NULL 33 + && rs_is_stream(js_get_slot(obj, SLOT_ENTRIES)); 34 + } 35 + 20 36 rs_stream_t *rs_get_stream(ant_value_t obj) { 21 37 ant_value_t s = js_get_slot(obj, SLOT_DATA); 22 38 if (vtype(s) != T_NUM) return NULL; ··· 164 180 165 181 ant_value_t stream_obj = rs_ctrl_stream(ctrl_obj); 166 182 ant_value_t reader_obj = rs_stream_reader(stream_obj); 167 - if (is_object_type(reader_obj) && rs_reader_has_reqs(js, reader_obj)) return true; 183 + if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) return true; 168 184 169 185 double desired = rs_default_controller_get_desired_size(ctrl, stream); 170 186 return desired > 0; ··· 179 195 180 196 void rs_fulfill_read_request(ant_t *js, ant_value_t stream_obj, ant_value_t chunk, bool done) { 181 197 ant_value_t reader_obj = rs_stream_reader(stream_obj); 182 - if (!is_object_type(reader_obj)) return; 198 + if (!rs_is_reader(reader_obj)) return; 183 199 ant_value_t promise = rs_reader_reqs_shift(js, reader_obj); 184 200 if (vtype(promise) == T_UNDEF) return; 185 201 ant_value_t result = js_iter_result(js, !done, chunk); ··· 202 218 stream->state = RS_STATE_CLOSED; 203 219 204 220 ant_value_t reader_obj = rs_stream_reader(stream_obj); 205 - if (is_object_type(reader_obj)) { 221 + if (rs_is_reader(reader_obj)) { 206 222 ant_value_t arr = rs_reader_reqs(reader_obj); 207 223 if (vtype(arr) == T_ARR) { 208 224 ant_offset_t len = js_arr_len(js, arr); ··· 224 240 js_set_slot(stream_obj, SLOT_BUFFER, e); 225 241 226 242 ant_value_t reader_obj = rs_stream_reader(stream_obj); 227 - if (is_object_type(reader_obj)) { 243 + if (rs_is_reader(reader_obj)) { 228 244 js_reject_promise(js, rs_reader_closed(reader_obj), e); 229 245 rs_default_reader_error_read_requests(js, reader_obj, e); 230 246 } ··· 436 452 ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef(); 437 453 438 454 ant_value_t reader_obj = rs_stream_reader(stream_obj); 439 - if (is_object_type(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { 455 + if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { 440 456 rs_fulfill_read_request(js, stream_obj, chunk, false); 441 457 rs_default_controller_call_pull_if_needed(js, js->this_val); 442 458 return js_mkundef(); ··· 510 526 return js_mkerr_typed(js, JS_ERR_TYPE, "The stream is not in a state that permits enqueue"); 511 527 512 528 ant_value_t reader_obj = rs_stream_reader(stream_obj); 513 - if (is_object_type(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { 529 + if (rs_is_reader(reader_obj) && rs_reader_has_reqs(js, reader_obj)) { 514 530 rs_fulfill_read_request(js, stream_obj, chunk, false); 515 531 rs_default_controller_call_pull_if_needed(js, ctrl_obj); 516 532 return js_mkundef(); ··· 581 597 582 598 static ant_value_t js_rs_reader_read(ant_t *js, ant_value_t *args, int nargs) { 583 599 ant_value_t stream_obj = rs_reader_stream(js->this_val); 584 - if (!is_object_type(stream_obj) || !rs_get_stream(stream_obj)) 600 + if (!rs_is_stream(stream_obj)) 585 601 return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot read from a released reader"); 586 602 return rs_default_reader_read(js, js->this_val); 587 603 } 588 604 589 605 static ant_value_t js_rs_reader_release_lock(ant_t *js, ant_value_t *args, int nargs) { 590 606 ant_value_t stream_obj = rs_reader_stream(js->this_val); 591 - if (!is_object_type(stream_obj)) return js_mkundef(); 607 + if (!rs_is_stream(stream_obj)) return js_mkundef(); 592 608 rs_stream_t *stream = rs_get_stream(stream_obj); 593 - if (!stream) return js_mkundef(); 594 609 595 610 if (rs_reader_has_reqs(js, js->this_val)) { 596 611 ant_value_t release_err = js_make_error_silent(js, JS_ERR_TYPE, "Reader was released"); ··· 617 632 618 633 static ant_value_t js_rs_reader_cancel(ant_t *js, ant_value_t *args, int nargs) { 619 634 ant_value_t stream_obj = rs_reader_stream(js->this_val); 620 - if (!is_object_type(stream_obj)) { 635 + if (!rs_is_stream(stream_obj)) { 621 636 ant_value_t p = js_mkpromise(js); 622 637 js_mkerr_typed(js, JS_ERR_TYPE, "Cannot cancel a released reader"); 623 638 js_reject_promise(js, p, js->thrown_value); ··· 633 648 if (nargs < 1) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader requires a stream argument"); 634 649 635 650 ant_value_t stream_obj = args[0]; 636 - if (!is_object_type(stream_obj)) 651 + if (!rs_is_stream(stream_obj)) 637 652 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader argument must be a ReadableStream"); 653 + 638 654 rs_stream_t *stream = rs_get_stream(stream_obj); 639 - if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStreamDefaultReader argument must be a ReadableStream"); 640 - if (is_object_type(rs_stream_reader(stream_obj))) 655 + if (rs_is_reader(rs_stream_reader(stream_obj))) 641 656 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked to a reader"); 642 657 643 658 ant_value_t closed = js_mkpromise(js); ··· 663 678 static ant_value_t js_rs_get_locked(ant_t *js, ant_value_t *args, int nargs) { 664 679 rs_stream_t *stream = rs_get_stream(js->this_val); 665 680 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 666 - return js_bool(is_object_type(rs_stream_reader(js->this_val))); 681 + return js_bool(rs_is_reader(rs_stream_reader(js->this_val))); 667 682 } 668 683 669 684 static ant_value_t js_rs_cancel(ant_t *js, ant_value_t *args, int nargs) { 670 685 rs_stream_t *stream = rs_get_stream(js->this_val); 671 686 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 672 - if (is_object_type(rs_stream_reader(js->this_val))) { 687 + if (rs_is_reader(rs_stream_reader(js->this_val))) { 673 688 ant_value_t p = js_mkpromise(js); 674 689 js_mkerr_typed(js, JS_ERR_TYPE, "Cannot cancel a locked ReadableStream"); 675 690 js_reject_promise(js, p, js->thrown_value);
+64 -58
src/streams/transform.c
··· 17 17 static ant_value_t g_ts_proto; 18 18 static ant_value_t g_ts_ctrl_proto; 19 19 20 + bool ts_is_controller(ant_value_t obj) { 21 + if (!is_object_type(obj)) return false; 22 + ant_value_t ts_obj = js_get_slot(obj, SLOT_DATA); 23 + return is_object_type(ts_obj) 24 + && vtype(js_get_slot(ts_obj, SLOT_DATA)) == T_NUM 25 + && js_get_slot(ts_obj, SLOT_DEFAULT) == obj; 26 + } 27 + 28 + bool ts_is_stream(ant_value_t obj) { 29 + return is_object_type(obj) 30 + && vtype(js_get_slot(obj, SLOT_DATA)) == T_NUM 31 + && rs_is_stream(js_get_slot(obj, SLOT_ENTRIES)) 32 + && ws_is_stream(js_get_slot(obj, SLOT_CTOR)) 33 + && ts_is_controller(js_get_slot(obj, SLOT_DEFAULT)); 34 + } 35 + 36 + ant_value_t ts_stream_readable(ant_value_t ts_obj) { 37 + return js_get_slot(ts_obj, SLOT_ENTRIES); 38 + } 39 + 40 + ant_value_t ts_stream_writable(ant_value_t ts_obj) { 41 + return js_get_slot(ts_obj, SLOT_CTOR); 42 + } 43 + 20 44 static void ts_ws_finalize(ant_t *js, ant_object_t *obj) { 21 45 if (!obj->extra_slots) return; 22 46 ant_extra_slot_t *entries = (ant_extra_slot_t *)obj->extra_slots; ··· 61 85 }} 62 86 } 63 87 64 - static inline bool ts_is_valid(ant_value_t ts_obj) { 65 - return vtype(js_get_slot(ts_obj, SLOT_DATA)) == T_NUM; 66 - } 67 - 68 88 static inline bool ts_get_backpressure(ant_value_t ts_obj) { 69 89 return js_getnum(js_get_slot(ts_obj, SLOT_DATA)) != 0; 70 90 } ··· 74 94 } 75 95 76 96 static inline ant_value_t ts_readable(ant_value_t ts_obj) { 77 - return js_get_slot(ts_obj, SLOT_ENTRIES); 97 + return ts_stream_readable(ts_obj); 78 98 } 79 99 80 100 static inline ant_value_t ts_writable(ant_value_t ts_obj) { 81 - return js_get_slot(ts_obj, SLOT_CTOR); 101 + return ts_stream_writable(ts_obj); 82 102 } 83 103 84 104 static inline ant_value_t ts_bp_promise(ant_value_t ts_obj) { ··· 175 195 return err; 176 196 } 177 197 178 - static bool ts_is_thenable(ant_t *js, ant_value_t val) { 179 - if (vtype(val) == T_PROMISE) return true; 180 - if (!is_object_type(val)) return false; 181 - ant_value_t then = js_get(js, val, "then"); 182 - return is_callable(then); 183 - } 198 + static void ts_chain_promise(ant_t *js, ant_value_t val, ant_value_t res_fn, ant_value_t rej_fn) { 199 + ant_value_t promise = val; 200 + if (vtype(promise) != T_PROMISE) { 201 + promise = js_mkpromise(js); 202 + js_resolve_promise(js, promise, val); 203 + } 184 204 185 - static void ts_chain_thenable(ant_t *js, ant_value_t val, ant_value_t res_fn, ant_value_t rej_fn) { 186 - if (vtype(val) == T_PROMISE) { 187 - ant_value_t then_fn = js_get(js, val, "then"); 188 - if (is_callable(then_fn)) { 189 - ant_value_t then_args[2] = { res_fn, rej_fn }; 190 - ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, val, then_args, 2, NULL, false); 191 - promise_mark_handled(then_result); 192 - }} else { 193 - ant_value_t resolved = js_mkpromise(js); 194 - js_resolve_promise(js, resolved, val); 195 - ant_value_t then_fn = js_get(js, resolved, "then"); 196 - if (is_callable(then_fn)) { 197 - ant_value_t then_args[2] = { res_fn, rej_fn }; 198 - ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, resolved, then_args, 2, NULL, false); 199 - promise_mark_handled(then_result); 200 - }} 205 + ant_value_t then_fn = js_get(js, promise, "then"); 206 + if (!is_callable(then_fn)) return; 207 + 208 + ant_value_t then_args[2] = { res_fn, rej_fn }; 209 + ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, promise, then_args, 2, NULL, false); 210 + promise_mark_handled(then_result); 201 211 } 202 212 203 213 static void ts_error(ant_t *js, ant_value_t ts_obj, ant_value_t e) { ··· 325 335 ant_value_t wrapper = js_mkobj(js); 326 336 js_set_slot(wrapper, SLOT_DATA, p); 327 337 js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); 338 + 328 339 ant_value_t rej_fn = js_heavy_mkfun(js, ts_transform_reject, wrapper); 329 - 330 - if (ts_is_thenable(js, result)) ts_chain_thenable(js, result, res_fn, rej_fn); 331 - else { 332 - ant_value_t resolved = js_mkpromise(js); 333 - js_resolve_promise(js, resolved, js_mkundef()); 334 - ts_chain_thenable(js, resolved, res_fn, rej_fn); 335 - } 340 + ts_chain_promise(js, result, res_fn, rej_fn); 336 341 } else { 337 342 ant_value_t enqueue_result = ts_ctrl_enqueue(js, ctrl_obj, chunk); 338 343 if (is_err(enqueue_result)) { ··· 390 395 ant_value_t wrapper = js_mkobj(js); 391 396 js_set_slot(wrapper, SLOT_DATA, p); 392 397 js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); 398 + 393 399 ant_value_t res_fn = js_heavy_mkfun(js, ts_cancel_base_resolve, wrapper); 394 400 ant_value_t rej_fn = js_heavy_mkfun(js, ts_cancel_base_reject, wrapper); 395 - 396 - if (ts_is_thenable(js, result)) ts_chain_thenable(js, result, res_fn, rej_fn); 397 - else { 398 - ant_value_t resolved = js_mkpromise(js); 399 - js_resolve_promise(js, resolved, js_mkundef()); 400 - ts_chain_thenable(js, resolved, res_fn, rej_fn); 401 - } 401 + ts_chain_promise(js, result, res_fn, rej_fn); 402 402 403 403 return p; 404 404 } ··· 448 448 449 449 ant_value_t readable = ts_readable(ts_obj); 450 450 rs_stream_t *rs = rs_get_stream(readable); 451 + 451 452 if (rs && rs->state == RS_STATE_ERRORED) { 452 453 js_reject_promise(js, p, rs_stream_error(readable)); 453 454 return js_mkundef(); 454 455 } 455 456 457 + if (ts_cancel_joined_abort(ts_obj)) js_set_slot(ts_obj, SLOT_RS_SIZE, reason); 456 458 ts_error(js, ts_obj, reason); 457 - js_resolve_promise(js, p, js_mkundef()); 459 + 460 + if (ts_cancel_joined_abort(ts_obj)) js_reject_promise(js, p, reason); 461 + else js_resolve_promise(js, p, js_mkundef()); 462 + 458 463 return js_mkundef(); 459 464 } 460 465 ··· 519 524 js_set_slot(rej_wrapper, SLOT_DATA, fp); 520 525 js_set_slot(rej_wrapper, SLOT_ENTRIES, ts_obj); 521 526 ant_value_t reject_fn = js_heavy_mkfun(js, ts_transform_reject, rej_wrapper); 522 - ts_chain_thenable(js, transform_p, resolve_fn, reject_fn); 527 + ts_chain_promise(js, transform_p, resolve_fn, reject_fn); 523 528 } 524 529 return js_mkundef(); 525 530 } ··· 544 549 js_set_slot(rej_wrapper, SLOT_ENTRIES, ts_obj); 545 550 ant_value_t rej_fn = js_heavy_mkfun(js, ts_transform_reject, rej_wrapper); 546 551 ant_value_t bp = ts_bp_promise(ts_obj); 547 - ts_chain_thenable(js, bp, res_fn, rej_fn); 552 + ts_chain_promise(js, bp, res_fn, rej_fn); 548 553 } else { 549 554 ant_value_t transform_p = ts_ctrl_perform_transform(js, ctrl_obj, chunk); 550 555 ant_value_t resolve_fn = js_heavy_mkfun(js, ts_transform_resolve, finish_p); ··· 552 557 js_set_slot(rej_wrapper, SLOT_DATA, finish_p); 553 558 js_set_slot(rej_wrapper, SLOT_ENTRIES, ts_obj); 554 559 ant_value_t reject_fn = js_heavy_mkfun(js, ts_transform_reject, rej_wrapper); 555 - ts_chain_thenable(js, transform_p, resolve_fn, reject_fn); 560 + ts_chain_promise(js, transform_p, resolve_fn, reject_fn); 556 561 } 557 562 558 563 return finish_p; ··· 563 568 ant_value_t ctrl_obj = ts_controller(ts_obj); 564 569 ant_value_t cancel_fn = ts_ctrl_cancel_fn(ctrl_obj); 565 570 ant_value_t reason = (nargs > 0) ? args[0] : js_mkundef(); 571 + 566 572 bool joined_source_cancel = vtype(ts_cancel_promise(ts_obj)) == T_PROMISE && !ts_cancel_started_by_abort(ts_obj); 567 - if (joined_source_cancel) js_set_slot(ts_obj, SLOT_WS_WRITE, js_true); 573 + if (joined_source_cancel && ts_cancel_has_user_handler(ts_obj)) 574 + js_set_slot(ts_obj, SLOT_WS_WRITE, js_true); 568 575 569 576 ant_value_t p = js_mkpromise(js); 570 577 ant_value_t base = ts_run_cancel_algorithm(js, ts_obj, cancel_fn, reason, true); ··· 573 580 js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); 574 581 js_set_slot(wrapper, SLOT_BUFFER, reason); 575 582 js_set_slot(wrapper, SLOT_CTOR, ts_cancel_started_by_abort(ts_obj) ? js_true : js_false); 583 + 576 584 ant_value_t res_fn = js_heavy_mkfun(js, ts_abort_cancel_resolve, wrapper); 577 585 ant_value_t rej_fn = js_heavy_mkfun(js, ts_abort_cancel_reject, wrapper); 578 - ts_chain_thenable(js, base, res_fn, rej_fn); 586 + ts_chain_promise(js, base, res_fn, rej_fn); 587 + 579 588 return p; 580 589 } 581 590 ··· 630 639 js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); 631 640 ant_value_t res_fn = js_heavy_mkfun(js, ts_close_cancel_resolve, wrapper); 632 641 ant_value_t rej_fn = js_heavy_mkfun(js, ts_close_cancel_reject, wrapper); 633 - ts_chain_thenable(js, cancel_p, res_fn, rej_fn); 642 + ts_chain_promise(js, cancel_p, res_fn, rej_fn); 634 643 return p; 635 644 } 636 645 ··· 655 664 ant_value_t res_fn = js_heavy_mkfun(js, ts_sink_close_resolve, wrapper); 656 665 ant_value_t rej_fn = js_heavy_mkfun(js, ts_sink_close_reject, wrapper); 657 666 658 - if (ts_is_thenable(js, result)) ts_chain_thenable(js, result, res_fn, rej_fn); 659 - else { 660 - ant_value_t resolved = js_mkpromise(js); 661 - js_resolve_promise(js, resolved, js_mkundef()); 662 - ts_chain_thenable(js, resolved, res_fn, rej_fn); 663 - } 667 + ts_chain_promise(js, result, res_fn, rej_fn); 664 668 } else { 665 669 rs_stream_t *rs = rs_get_stream(readable); 666 670 if (rs && rs->state == RS_STATE_READABLE) { ··· 719 723 js_set_slot(wrapper, SLOT_CTOR, ts_cancel_started_by_abort(ts_obj) ? js_true : js_false); 720 724 ant_value_t res_fn = js_heavy_mkfun(js, ts_source_cancel_resolve, wrapper); 721 725 ant_value_t rej_fn = js_heavy_mkfun(js, ts_source_cancel_reject, wrapper); 722 - ts_chain_thenable(js, base, res_fn, rej_fn); 726 + ts_chain_promise(js, base, res_fn, rej_fn); 723 727 return p; 724 728 } 725 729 ··· 758 762 } 759 763 760 764 static ant_value_t js_ts_get_readable(ant_t *js, ant_value_t *args, int nargs) { 761 - if (!ts_is_valid(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid TransformStream"); 765 + if (!ts_is_stream(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid TransformStream"); 762 766 return ts_readable(js->this_val); 763 767 } 764 768 765 769 static ant_value_t js_ts_get_writable(ant_t *js, ant_value_t *args, int nargs) { 766 - if (!ts_is_valid(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid TransformStream"); 770 + if (!ts_is_stream(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid TransformStream"); 767 771 return ts_writable(js->this_val); 768 772 } 769 773 ··· 807 811 ws_stream_t *ws = ws_get_stream(writable); 808 812 if (ws && ws->state == WS_STATE_WRITABLE) 809 813 ws_default_controller_error(js, ws_ctrl, e); 814 + else if (ws && ws->state == WS_STATE_ERRORING) 815 + writable_stream_finish_erroring(js, writable); 810 816 811 817 return js_mkundef(); 812 818 }
+51 -63
src/streams/writable.c
··· 18 18 ant_value_t g_ws_controller_proto; 19 19 static ant_value_t g_close_sentinel; 20 20 21 + bool ws_is_stream(ant_value_t obj) { 22 + return is_object_type(obj) && ws_get_stream(obj) != NULL; 23 + } 24 + 25 + bool ws_is_writer(ant_value_t obj) { 26 + return is_object_type(obj) 27 + && vtype(js_get_slot(obj, SLOT_RS_CLOSED)) == T_PROMISE 28 + && vtype(js_get_slot(obj, SLOT_WS_READY)) == T_PROMISE; 29 + } 30 + 31 + bool ws_is_controller(ant_value_t obj) { 32 + return is_object_type(obj) 33 + && ws_get_controller(obj) != NULL 34 + && ws_is_stream(js_get_slot(obj, SLOT_ENTRIES)); 35 + } 36 + 21 37 ws_stream_t *ws_get_stream(ant_value_t obj) { 22 38 ant_value_t s = js_get_slot(obj, SLOT_DATA); 23 39 if (vtype(s) != T_NUM) return NULL; ··· 179 195 return val; 180 196 } 181 197 182 - static bool ws_is_thenable(ant_t *js, ant_value_t val) { 183 - if (vtype(val) == T_PROMISE) return true; 184 - if (!is_object_type(val)) return false; 185 - ant_value_t then = js_get(js, val, "then"); 186 - return is_callable(then); 187 - } 188 - 189 - static void ws_chain_thenable(ant_t *js, ant_value_t val, ant_value_t res_fn, ant_value_t rej_fn) { 190 - if (vtype(val) == T_PROMISE) { 191 - ant_value_t then_fn = js_get(js, val, "then"); 192 - if (is_callable(then_fn)) { 193 - ant_value_t then_args[2] = { res_fn, rej_fn }; 194 - ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, val, then_args, 2, NULL, false); 195 - promise_mark_handled(then_result); 196 - }} else { 197 - ant_value_t resolved = js_mkpromise(js); 198 - js_resolve_promise(js, resolved, val); 199 - ant_value_t then_fn = js_get(js, resolved, "then"); 200 - if (is_callable(then_fn)) { 201 - ant_value_t then_args[2] = { res_fn, rej_fn }; 202 - ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, resolved, then_args, 2, NULL, false); 203 - promise_mark_handled(then_result); 198 + static void ws_chain_promise(ant_t *js, ant_value_t val, ant_value_t res_fn, ant_value_t rej_fn) { 199 + ant_value_t promise = val; 200 + if (vtype(promise) != T_PROMISE) { 201 + promise = js_mkpromise(js); 202 + js_resolve_promise(js, promise, val); 204 203 } 205 - }} 204 + 205 + ant_value_t then_fn = js_get(js, promise, "then"); 206 + if (!is_callable(then_fn)) return; 207 + 208 + ant_value_t then_args[2] = { res_fn, rej_fn }; 209 + ant_value_t then_result = sv_vm_call(js->vm, js, then_fn, promise, then_args, 2, NULL, false); 210 + promise_mark_handled(then_result); 211 + } 206 212 207 213 static void ws_default_controller_clear_algorithms(ant_value_t ctrl_obj) { 208 214 js_set_slot(ctrl_obj, SLOT_WS_WRITE, js_mkundef()); ··· 268 274 ant_value_t signal_ac = ws_ctrl_signal(ctrl_obj); 269 275 if (is_object_type(signal_ac)) { 270 276 ant_value_t signal = js_get(js, signal_ac, "signal"); 271 - if (is_object_type(signal)) 277 + if (abort_signal_is_signal(signal)) 272 278 signal_do_abort(js, signal, reason); 273 279 } 274 280 275 281 ant_value_t writer_obj = ws_stream_writer(stream_obj); 276 - if (is_object_type(writer_obj)) 282 + if (ws_is_writer(writer_obj)) 277 283 ws_writer_reject_ready_promise(js, writer_obj, reason); 278 284 279 285 if (!writable_stream_has_operation_in_flight(stream_obj) && ctrl && ctrl->started) ··· 288 294 js_set_slot(stream_obj, SLOT_WS_CLOSE, js_mkundef()); 289 295 } 290 296 ant_value_t writer_obj = ws_stream_writer(stream_obj); 291 - if (is_object_type(writer_obj)) 297 + if (ws_is_writer(writer_obj)) 292 298 ws_writer_reject_closed_promise(js, writer_obj, stored_error); 293 299 } 294 300 ··· 365 371 js_set_slot(wrapper, SLOT_ENTRIES, stream_obj); 366 372 ant_value_t res_fn = js_heavy_mkfun(js, ws_finish_erroring_abort_resolve, wrapper); 367 373 ant_value_t rej_fn = js_heavy_mkfun(js, ws_finish_erroring_abort_reject, wrapper); 368 - if (ws_is_thenable(js, result)) ws_chain_thenable(js, result, res_fn, rej_fn); 369 - else { 370 - ant_value_t resolved = js_mkpromise(js); 371 - js_resolve_promise(js, resolved, js_mkundef()); 372 - ws_chain_thenable(js, resolved, res_fn, rej_fn); 373 - } 374 + ws_chain_promise(js, result, res_fn, rej_fn); 374 375 } 375 376 376 377 return; ··· 394 395 if (!stream) return; 395 396 ant_value_t writer_obj = ws_stream_writer(stream_obj); 396 397 397 - if (is_object_type(writer_obj) && stream->backpressure != backpressure) { 398 + if (ws_is_writer(writer_obj) && stream->backpressure != backpressure) { 398 399 if (backpressure) { 399 400 ant_value_t ready = js_mkpromise(js); 400 401 promise_mark_handled(ready); ··· 440 441 stream->state = WS_STATE_CLOSED; 441 442 442 443 ant_value_t writer_obj = ws_stream_writer(stream_obj); 443 - if (is_object_type(writer_obj)) { 444 + if (ws_is_writer(writer_obj)) { 444 445 ant_value_t closed = ws_writer_closed(writer_obj); 445 446 if (!is_undefined(closed)) js_resolve_promise(js, closed, js_mkundef()); 446 447 } ··· 529 530 } else { 530 531 ant_value_t res_fn = js_heavy_mkfun(js, ws_process_write_resolve, ctrl_obj); 531 532 ant_value_t rej_fn = js_heavy_mkfun(js, ws_process_write_reject, ctrl_obj); 532 - if (ws_is_thenable(js, result)) ws_chain_thenable(js, result, res_fn, rej_fn); 533 - else { 534 - ant_value_t resolved = js_mkpromise(js); 535 - js_resolve_promise(js, resolved, js_mkundef()); 536 - ws_chain_thenable(js, resolved, res_fn, rej_fn); 537 - } 533 + ws_chain_promise(js, result, res_fn, rej_fn); 538 534 } 539 535 } 540 536 ··· 577 573 } else { 578 574 ant_value_t res_fn = js_heavy_mkfun(js, ws_process_close_resolve, stream_obj); 579 575 ant_value_t rej_fn = js_heavy_mkfun(js, ws_process_close_reject, stream_obj); 580 - if (ws_is_thenable(js, result)) { 581 - ws_chain_thenable(js, result, res_fn, rej_fn); 582 - } else { 583 - ant_value_t resolved = js_mkpromise(js); 584 - js_resolve_promise(js, resolved, js_mkundef()); 585 - ws_chain_thenable(js, resolved, res_fn, rej_fn); 586 - } 576 + ws_chain_promise(js, result, res_fn, rej_fn); 587 577 } 588 578 } 589 579 ··· 680 670 js_set_slot(stream_obj, SLOT_WS_CLOSE, promise); 681 671 682 672 ant_value_t writer_obj = ws_stream_writer(stream_obj); 683 - if (is_object_type(writer_obj) && stream->backpressure && stream->state == WS_STATE_WRITABLE) { 673 + if (ws_is_writer(writer_obj) && stream->backpressure && stream->state == WS_STATE_WRITABLE) { 684 674 ant_value_t ready = ws_writer_ready(writer_obj); 685 675 if (!is_undefined(ready)) js_resolve_promise(js, ready, js_mkundef()); 686 676 } ··· 710 700 } 711 701 712 702 ant_value_t writer_obj = ws_stream_writer(stream_obj); 713 - if (is_object_type(writer_obj)) ws_writer_reject_closed_promise(js, writer_obj, stored_error); 703 + if (ws_is_writer(writer_obj)) ws_writer_reject_closed_promise(js, writer_obj, stored_error); 714 704 715 705 return js_mkundef(); 716 706 } ··· 735 725 } 736 726 737 727 ant_value_t writer_obj = ws_stream_writer(stream_obj); 738 - if (is_object_type(writer_obj)) 728 + if (ws_is_writer(writer_obj)) 739 729 ws_writer_reject_closed_promise(js, writer_obj, stored_error); 740 730 741 731 return js_mkundef(); ··· 770 760 771 761 ant_value_t ws_writer_write(ant_t *js, ant_value_t writer_obj, ant_value_t chunk) { 772 762 ant_value_t stream_obj = ws_writer_stream(writer_obj); 773 - if (!is_object_type(stream_obj)) { 763 + if (!ws_is_stream(stream_obj)) { 774 764 ant_value_t p = js_mkpromise(js); 775 765 js_mkerr_typed(js, JS_ERR_TYPE, "Writer has no stream"); 776 766 js_reject_promise(js, p, js->thrown_value); ··· 893 883 894 884 static ant_value_t js_ws_writer_get_desired_size(ant_t *js, ant_value_t *args, int nargs) { 895 885 ant_value_t stream_obj = ws_writer_stream(js->this_val); 896 - if (!is_object_type(stream_obj)) 886 + if (!ws_is_stream(stream_obj)) 897 887 return js_mkerr_typed(js, JS_ERR_TYPE, "Writer has no stream"); 898 888 ws_stream_t *stream = ws_get_stream(stream_obj); 899 889 if (!stream) return js_mknull(); ··· 907 897 908 898 static ant_value_t js_ws_writer_abort(ant_t *js, ant_value_t *args, int nargs) { 909 899 ant_value_t stream_obj = ws_writer_stream(js->this_val); 910 - if (!is_object_type(stream_obj)) { 900 + if (!ws_is_stream(stream_obj)) { 911 901 ant_value_t p = js_mkpromise(js); 912 902 js_mkerr_typed(js, JS_ERR_TYPE, "Writer has no stream"); 913 903 js_reject_promise(js, p, js->thrown_value); ··· 919 909 920 910 static ant_value_t js_ws_writer_close(ant_t *js, ant_value_t *args, int nargs) { 921 911 ant_value_t stream_obj = ws_writer_stream(js->this_val); 922 - if (!is_object_type(stream_obj)) { 912 + if (!ws_is_stream(stream_obj)) { 923 913 ant_value_t p = js_mkpromise(js); 924 914 js_mkerr_typed(js, JS_ERR_TYPE, "Writer has no stream"); 925 915 js_reject_promise(js, p, js->thrown_value); ··· 936 926 937 927 static ant_value_t js_ws_writer_release_lock(ant_t *js, ant_value_t *args, int nargs) { 938 928 ant_value_t stream_obj = ws_writer_stream(js->this_val); 939 - if (!is_object_type(stream_obj)) return js_mkundef(); 929 + if (!ws_is_stream(stream_obj)) return js_mkundef(); 940 930 ant_value_t release_err = js_make_error_silent(js, JS_ERR_TYPE, "Writer was released"); 941 931 942 932 ws_writer_reject_ready_promise(js, js->this_val, release_err); ··· 956 946 957 947 static ant_value_t js_ws_writer_write(ant_t *js, ant_value_t *args, int nargs) { 958 948 ant_value_t stream_obj = ws_writer_stream(js->this_val); 959 - if (!is_object_type(stream_obj)) { 949 + if (!ws_is_stream(stream_obj)) { 960 950 ant_value_t p = js_mkpromise(js); 961 951 js_mkerr_typed(js, JS_ERR_TYPE, "Writer has no stream"); 962 952 js_reject_promise(js, p, js->thrown_value); ··· 973 963 return js_mkerr_typed(js, JS_ERR_TYPE, "WritableStreamDefaultWriter requires a stream argument"); 974 964 975 965 ant_value_t stream_obj = args[0]; 976 - if (!is_object_type(stream_obj)) 966 + if (!ws_is_stream(stream_obj)) 977 967 return js_mkerr_typed(js, JS_ERR_TYPE, "WritableStreamDefaultWriter argument must be a WritableStream"); 978 968 ws_stream_t *stream = ws_get_stream(stream_obj); 979 - if (!stream) 980 - return js_mkerr_typed(js, JS_ERR_TYPE, "WritableStreamDefaultWriter argument must be a WritableStream"); 981 - if (is_object_type(ws_stream_writer(stream_obj))) 969 + if (ws_is_writer(ws_stream_writer(stream_obj))) 982 970 return js_mkerr_typed(js, JS_ERR_TYPE, "WritableStream is already locked to a writer"); 983 971 984 972 ant_value_t obj = js_mkobj(js); ··· 1027 1015 static ant_value_t js_ws_get_locked(ant_t *js, ant_value_t *args, int nargs) { 1028 1016 ws_stream_t *stream = ws_get_stream(js->this_val); 1029 1017 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid WritableStream"); 1030 - return js_bool(is_object_type(ws_stream_writer(js->this_val))); 1018 + return js_bool(ws_is_writer(ws_stream_writer(js->this_val))); 1031 1019 } 1032 1020 1033 1021 static ant_value_t js_ws_abort(ant_t *js, ant_value_t *args, int nargs) { 1034 1022 ws_stream_t *stream = ws_get_stream(js->this_val); 1035 1023 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid WritableStream"); 1036 - if (is_object_type(ws_stream_writer(js->this_val))) { 1024 + if (ws_is_writer(ws_stream_writer(js->this_val))) { 1037 1025 ant_value_t p = js_mkpromise(js); 1038 1026 js_mkerr_typed(js, JS_ERR_TYPE, "Cannot abort a locked WritableStream"); 1039 1027 js_reject_promise(js, p, js->thrown_value); ··· 1046 1034 static ant_value_t js_ws_close(ant_t *js, ant_value_t *args, int nargs) { 1047 1035 ws_stream_t *stream = ws_get_stream(js->this_val); 1048 1036 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid WritableStream"); 1049 - if (is_object_type(ws_stream_writer(js->this_val))) { 1037 + if (ws_is_writer(ws_stream_writer(js->this_val))) { 1050 1038 ant_value_t p = js_mkpromise(js); 1051 1039 js_mkerr_typed(js, JS_ERR_TYPE, "Cannot close a locked WritableStream"); 1052 1040 js_reject_promise(js, p, js->thrown_value);