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.

migrate to internal slots for all of pipes

+31 -69
+3
examples/spec/streams-pipe.js
··· 243 243 test('pipeTo with signal should reject', false, true); 244 244 } catch (e) { 245 245 test('pipeTo aborted by signal', true, true); 246 + test('pipeTo signal rejects with abort semantics', 247 + !(e instanceof TypeError) && !(e && /AbortSignal/.test(String(e && e.message))), 248 + true); 246 249 } 247 250 testDeep('pipeTo signal stops further writes', chunks, ['a']); 248 251 }
+8 -6
src/modules/abort.c
··· 109 109 ant_value_t call_args[1] = { event_obj }; 110 110 111 111 ant_value_t onabort = js_get(js, *cur, "onabort"); 112 - if (vtype(onabort) == T_FUNC) { 112 + if (is_callable(onabort)) { 113 113 sv_vm_call(js->vm, js, onabort, *cur, call_args, 1, NULL, false); 114 114 process_microtasks(js); 115 115 } ··· 117 117 unsigned int n = utarray_len(d->listeners); 118 118 for (unsigned int i = 0; i < n;) { 119 119 abort_listener_t *entry = (abort_listener_t *)utarray_eltptr(d->listeners, i); 120 - ant_value_t cb = entry->callback; 121 - bool once = entry->once; 120 + ant_value_t cb = entry->callback; 121 + bool once = entry->once; 122 + 122 123 if (once) { utarray_erase(d->listeners, i, 1); n--; } else i++; 123 - if (vtype(cb) != T_FUNC) continue; 124 + if (!is_callable(cb)) continue; 125 + 124 126 sv_vm_call(js->vm, js, cb, *cur, call_args, 1, NULL, false); 125 127 process_microtasks(js); 126 128 }} 129 + 127 130 utarray_free(to_fire); 128 131 } 129 132 ··· 155 158 156 159 const char *type = js_getstr(js, args[0], NULL); 157 160 if (!type || strcmp(type, "abort") != 0) return js_mkundef(); 158 - if (vtype(args[1]) != T_FUNC) return js_mkundef(); 161 + if (!is_callable(args[1])) return js_mkundef(); 159 162 160 163 abort_signal_data_t *data = get_signal_data(js_getthis(js)); 161 164 if (!data) return js_mkundef(); ··· 413 416 abort_listener_t entry = { callback, false }; 414 417 utarray_push_back(data->listeners, &entry); 415 418 } 416 -
+20 -63
src/streams/pipes.c
··· 7 7 8 8 #include "silver/engine.h" 9 9 #include "modules/assert.h" 10 - #include "modules/domexception.h" 10 + #include "modules/abort.h" 11 11 #include "streams/pipes.h" 12 12 #include "streams/readable.h" 13 13 #include "streams/writable.h" 14 - 15 - static ant_value_t pipes_call_method( 16 - ant_t *js, ant_value_t obj, const char *name, 17 - ant_value_t *args, int nargs 18 - ) { 19 - ant_value_t fn = js_get(js, obj, name); 20 - if (!is_callable(fn)) return js_mkundef(); 21 - return sv_vm_call(js->vm, js, fn, obj, args, nargs, NULL, false); 22 - } 23 - 24 - static bool pipes_get_bool(ant_t *js, ant_value_t obj, const char *name) { 25 - return js_truthy(js, js_get(js, obj, name)); 26 - } 27 - 28 - static void pipes_set_bool(ant_t *js, ant_value_t obj, const char *name, bool value) { 29 - js_set(js, obj, name, js_bool(value)); 30 - } 31 - 32 - static ant_value_t pipes_abort_reason(ant_t *js, ant_value_t signal) { 33 - ant_value_t reason = js_get(js, signal, "reason"); 34 - if (!is_undefined(reason)) return reason; 35 - return make_dom_exception(js, "signal is aborted without reason", "AbortError"); 36 - } 37 - 38 - static bool pipes_is_abort_signal(ant_t *js, ant_value_t signal) { 39 - if (!is_object_type(signal)) return false; 40 - ant_value_t aborted = js_get(js, signal, "aborted"); 41 - ant_value_t add = js_get(js, signal, "addEventListener"); 42 - ant_value_t remove = js_get(js, signal, "removeEventListener"); 43 - return vtype(aborted) == T_BOOL && is_callable(add) && is_callable(remove); 44 - } 45 14 46 15 static void pipes_chain_thenable( 47 16 ant_t *js, ant_value_t value, ··· 165 134 } 166 135 } 167 136 168 - static void pipes_remove_abort_listener(ant_t *js, ant_value_t state) { 169 - ant_value_t signal = js_get(js, state, "signal"); 170 - ant_value_t listener = js_get(js, state, "abortListener"); 171 - if (!is_object_type(signal) || !is_callable(listener)) return; 172 - 173 - ant_value_t args[2] = { 174 - js_mkstr(js, "abort", 5), 175 - listener 176 - }; 177 - 178 - pipes_call_method(js, signal, "removeEventListener", args, 2); 179 - js_set(js, state, "abortListener", js_mkundef()); 180 - } 181 - 182 137 static void pipes_settle(ant_t *js, ant_value_t state, bool ok, ant_value_t value) { 183 138 pipe_state_t *pst = pipe_get_state(state); 184 139 if (!pst || pst->settled) return; 185 140 186 141 pst->settled = true; 187 142 pst->shutting_down = true; 188 - pipes_remove_abort_listener(js, state); 189 143 pipes_release_locks(js, state); 190 144 191 145 ant_value_t promise = pipe_state_promise(state); ··· 340 294 if (!pst || pst->settled || pst->shutting_down) 341 295 return js_mkundef(); 342 296 343 - ant_value_t signal = js_get(js, state, "signal"); 344 - pipes_shutdown_from_abort(js, state, pipes_abort_reason(js, signal)); 297 + ant_value_t signal = js_get_slot(state, SLOT_RS_CANCEL); 298 + pipes_shutdown_from_abort(js, state, abort_signal_get_reason(signal)); 345 299 return js_mkundef(); 346 300 } 347 301 ··· 403 357 return pipe_create_rejected(js, js->thrown_value); 404 358 } 405 359 406 - if (!is_undefined(signal) && !pipes_is_abort_signal(js, signal)) { 360 + if (!is_undefined(signal) && !is_object_type(signal)) { 407 361 js_mkerr_typed(js, JS_ERR_TYPE, "pipeTo option 'signal' must be an AbortSignal"); 408 362 return pipe_create_rejected(js, js->thrown_value); 409 363 } ··· 436 390 js_set_slot(state, SLOT_DEFAULT, writer); 437 391 js_set_slot(state, SLOT_RS_PULL, promise); 438 392 js_set_finalizer(state, pipe_state_finalize); 393 + js_set_slot(state, SLOT_RS_CANCEL, signal); 439 394 440 - js_set(js, state, "signal", signal); 441 - js_set(js, state, "abortListener", js_mkundef()); 395 + promise_mark_handled(rs_reader_closed(reader)); 396 + promise_mark_handled(js_get_slot(writer, SLOT_RS_CLOSED)); 397 + promise_mark_handled(js_get_slot(writer, SLOT_WS_READY)); 442 398 443 - if (is_object_type(signal) && js_truthy(js, js_get(js, signal, "aborted"))) { 444 - pipes_shutdown_from_abort(js, state, pipes_abort_reason(js, signal)); 399 + if (is_object_type(signal) && abort_signal_is_aborted(signal)) { 400 + pipes_shutdown_from_abort(js, state, abort_signal_get_reason(signal)); 445 401 return promise; 446 402 } 447 403 448 404 if (is_object_type(signal)) { 449 405 ant_value_t listener = js_heavy_mkfun(js, pipe_abort_listener, state); 450 - ant_value_t options = js_mkobj(js); 451 - js_set(js, options, "once", js_true); 452 - ant_value_t args[3] = { 453 - js_mkstr(js, "abort", 5), 454 - listener, 455 - options 456 - }; 457 - pipes_call_method(js, signal, "addEventListener", args, 3); 458 - js_set(js, state, "abortListener", listener); 406 + abort_signal_add_listener(js, signal, listener); 459 407 } 460 408 461 409 pipes_pump(js, state); ··· 463 411 } 464 412 465 413 static ant_value_t js_rs_pipe_to(ant_t *js, ant_value_t *args, int nargs) { 414 + if (!is_object_type(js->this_val)) { 415 + js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 416 + return pipe_create_rejected(js, js->thrown_value); 417 + } 418 + 466 419 rs_stream_t *stream = rs_get_stream(js->this_val); 467 420 if (!stream) { 468 421 js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); ··· 479 432 } 480 433 481 434 static ant_value_t js_rs_pipe_through(ant_t *js, ant_value_t *args, int nargs) { 435 + if (!is_object_type(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 482 436 rs_stream_t *stream = rs_get_stream(js->this_val); 437 + 483 438 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 484 439 if (is_object_type(rs_stream_reader(js->this_val))) 485 440 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked"); ··· 758 713 } 759 714 760 715 static ant_value_t js_rs_tee(ant_t *js, ant_value_t *args, int nargs) { 716 + if (!is_object_type(js->this_val)) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 761 717 rs_stream_t *stream = rs_get_stream(js->this_val); 718 + 762 719 if (!stream) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid ReadableStream"); 763 720 if (is_object_type(rs_stream_reader(js->this_val))) 764 721 return js_mkerr_typed(js, JS_ERR_TYPE, "ReadableStream is already locked");