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.

fix segfault in node:net

+318 -154
+14 -1
include/modules/events.h
··· 1 1 #ifndef EVENTS_H 2 2 #define EVENTS_H 3 3 4 + #include <stdbool.h> 4 5 #include "types.h" 5 6 6 7 ant_value_t events_library(ant_t *js); ··· 8 9 void init_events_module(void); 9 10 void js_dispatch_global_event(ant_t *js, ant_value_t event_obj); 10 11 11 - #endif 12 + bool eventemitter_add_listener( 13 + ant_t *js, 14 + ant_value_t target, const char *event_type, 15 + ant_value_t listener, bool once 16 + ); 17 + 18 + bool eventemitter_emit_args( 19 + ant_t *js, 20 + ant_value_t target, const char *event_type, 21 + ant_value_t *args, int nargs 22 + ); 23 + 24 + #endif
+4
src/modules/buffer.c
··· 39 39 } 40 40 41 41 bool buffer_source_get_bytes(ant_t *js, ant_value_t value, const uint8_t **out, size_t *len) { 42 + if (out) *out = NULL; 43 + if (len) *len = 0; 44 + if (vtype(value) != T_TYPEDARRAY && !is_object_type(value)) return false; 45 + 42 46 ant_value_t slot = js_get_slot(value, SLOT_BUFFER); 43 47 TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); 44 48
+96 -36
src/modules/events.c
··· 539 539 dispatch_event_to(js, event_obj, evt, js_glob(js)); 540 540 } 541 541 542 - static ant_value_t js_eventemitter_add(ant_t *js, ant_value_t *args, int nargs, bool once) { 543 - if (nargs < 2) return js_mkerr(js, "requires 2 arguments (event, listener)"); 544 - const char *event_type = js_getstr(js, args[0], NULL); 545 - if (!event_type) return js_mkerr(js, "event must be a string"); 546 - uint8_t t = vtype(args[1]); 547 - if (t != T_FUNC && t != T_CFUNC) return js_mkerr(js, "listener must be a function"); 542 + static bool eventemitter_add_listener_impl( 543 + ant_t *js, 544 + ant_value_t target, const char *event_type, 545 + ant_value_t listener, bool once 546 + ) { 547 + EventType *evt = NULL; 548 + EventListenerEntry entry = {0}; 549 + uint8_t t = 0; 548 550 549 - ant_value_t this_obj = js_getthis(js); 550 - EventType *evt = find_or_create_emitter_event_type(js, this_obj, event_type); 551 - if (!evt) return js_mkerr(js, "failed to create event type"); 551 + if (!is_object_type(target) || !event_type) return false; 552 + t = vtype(listener); 553 + if (t != T_FUNC && t != T_CFUNC) return false; 552 554 553 - EventListenerEntry entry = { args[1], js_mkundef(), once, false }; 554 - utarray_push_back(evt->listeners, &entry); 555 - return this_obj; 556 - } 555 + evt = find_or_create_emitter_event_type(js, target, event_type); 556 + if (!evt) return false; 557 557 558 - static ant_value_t js_eventemitter_on(ant_t *js, ant_value_t *args, int nargs) { 559 - return js_eventemitter_add(js, args, nargs, false); 560 - } 558 + entry.callback = listener; 559 + entry.signal = js_mkundef(); 560 + entry.once = once; 561 + entry.capture = false; 562 + utarray_push_back(evt->listeners, &entry); 561 563 562 - static ant_value_t js_eventemitter_once(ant_t *js, ant_value_t *args, int nargs) { 563 - return js_eventemitter_add(js, args, nargs, true); 564 + return true; 564 565 } 565 566 566 567 static ant_value_t js_eventemitter_off(ant_t *js, ant_value_t *args, int nargs) { 567 568 if (nargs < 2) return js_mkerr(js, "off requires 2 arguments (event, listener)"); 568 569 const char *event_type = js_getstr(js, args[0], NULL); 570 + 569 571 if (!event_type) return js_mkerr(js, "event must be a string"); 570 572 ant_value_t this_obj = js_getthis(js); 571 - remove_listener_from(js, args, nargs, find_emitter_event_type(js, this_obj, event_type)); 573 + 574 + remove_listener_from( 575 + js, args, nargs, 576 + find_emitter_event_type(js, this_obj, event_type) 577 + ); 578 + 572 579 return this_obj; 573 580 } 574 581 575 - static ant_value_t js_eventemitter_emit(ant_t *js, ant_value_t *args, int nargs) { 576 - if (nargs < 1) return js_mkerr(js, "emit requires at least 1 argument (event)"); 577 - const char *event_type = js_getstr(js, args[0], NULL); 578 - if (!event_type) return js_mkerr(js, "event must be a string"); 579 - 580 - ant_value_t this_obj = js_getthis(js); 581 - EventType *evt = find_emitter_event_type(js, this_obj, event_type); 582 - if (!evt || utarray_len(evt->listeners) == 0) return js_false; 582 + static bool eventemitter_emit_args_impl( 583 + ant_t *js, 584 + ant_value_t target, const char *event_type, 585 + ant_value_t *args, int nargs 586 + ) { 587 + EventType *evt = NULL; 583 588 584 - int listener_nargs = nargs - 1; 585 - ant_value_t *listener_args = listener_nargs > 0 ? &args[1] : NULL; 589 + if (!is_object_type(target) || !event_type) return false; 590 + evt = find_emitter_event_type(js, target, event_type); 591 + if (!evt || utarray_len(evt->listeners) == 0) return false; 586 592 587 593 for (unsigned int i = 0; i < utarray_len(evt->listeners);) { 588 594 EventListenerEntry *entry = (EventListenerEntry *)utarray_eltptr(evt->listeners, i); 589 595 ant_value_t cb = entry->callback; 590 596 bool once = entry->once; 591 - if (once) { utarray_erase(evt->listeners, i, 1); } else i++; 592 - uint8_t t = vtype(cb); 593 - if (t != T_FUNC && t != T_CFUNC) continue; 594 - ant_value_t result = sv_vm_call(js->vm, js, cb, js_mkundef(), listener_args, listener_nargs, NULL, false); 595 - if (vtype(result) == T_ERR) 596 - fprintf(stderr, "Error in event listener for '%s': %s\n", event_type, js_str(js, result)); 597 + 598 + if (once) utarray_erase(evt->listeners, i, 1); 599 + else i++; 600 + 601 + if (vtype(entry->signal) != T_UNDEF && abort_signal_is_aborted(entry->signal)) continue; 602 + if (vtype(cb) != T_FUNC && vtype(cb) != T_CFUNC) continue; 603 + 604 + ant_value_t result = sv_vm_call(js->vm, js, cb, js_mkundef(), args, nargs, NULL, false); 605 + if (vtype(result) == T_ERR) fprintf(stderr, "Error in event listener for '%s': %s\n", event_type, js_str(js, result)); 597 606 } 598 - return js_true; 607 + 608 + return true; 609 + } 610 + 611 + static ant_value_t js_eventemitter_emit(ant_t *js, ant_value_t *args, int nargs) { 612 + const char *event_type = NULL; 613 + 614 + if (nargs < 1) return js_mkerr(js, "emit requires at least 1 argument (event)"); 615 + event_type = js_getstr(js, args[0], NULL); 616 + if (!event_type) return js_mkerr(js, "event must be a string"); 617 + 618 + return js_bool(eventemitter_emit_args_impl( 619 + js, js_getthis(js), event_type, 620 + nargs > 1 ? &args[1] : NULL, nargs - 1 621 + )); 622 + } 623 + 624 + bool eventemitter_emit_args( 625 + ant_t *js, 626 + ant_value_t target, const char *event_type, 627 + ant_value_t *args, int nargs 628 + ) { 629 + return eventemitter_emit_args_impl(js, target, event_type, args, nargs); 630 + } 631 + 632 + bool eventemitter_add_listener( 633 + ant_t *js, 634 + ant_value_t target, const char *event_type, 635 + ant_value_t listener, bool once 636 + ) { 637 + return eventemitter_add_listener_impl(js, target, event_type, listener, once); 638 + } 639 + 640 + static ant_value_t js_eventemitter_add(ant_t *js, ant_value_t *args, int nargs, bool once) { 641 + const char *event_type = NULL; 642 + 643 + if (nargs < 2) return js_mkerr(js, "requires 2 arguments (event, listener)"); 644 + event_type = js_getstr(js, args[0], NULL); 645 + 646 + if (!event_type) return js_mkerr(js, "event must be a string"); 647 + if (!eventemitter_add_listener_impl(js, js_getthis(js), event_type, args[1], once)) 648 + return js_mkerr(js, "listener must be a function"); 649 + 650 + return js_getthis(js); 651 + } 652 + 653 + static ant_value_t js_eventemitter_on(ant_t *js, ant_value_t *args, int nargs) { 654 + return js_eventemitter_add(js, args, nargs, false); 655 + } 656 + 657 + static ant_value_t js_eventemitter_once(ant_t *js, ant_value_t *args, int nargs) { 658 + return js_eventemitter_add(js, args, nargs, true); 599 659 } 600 660 601 661 static ant_value_t js_eventemitter_removeAllListeners(ant_t *js, ant_value_t *args, int nargs) {
+204 -117
src/modules/net.c
··· 29 29 typedef struct net_server_s net_server_t; 30 30 typedef struct net_socket_s net_socket_t; 31 31 32 + typedef struct net_listen_args_s net_listen_args_t; 33 + typedef struct net_write_args_s net_write_args_t; 34 + 32 35 struct net_socket_s { 33 36 ant_t *js; 34 37 ant_value_t obj; ··· 61 64 unsigned int keep_alive_initial_delay_secs; 62 65 }; 63 66 67 + struct net_listen_args_s { 68 + const char *host; 69 + int port; 70 + int backlog; 71 + ant_value_t callback; 72 + ant_value_t error; 73 + }; 74 + 75 + struct net_write_args_s { 76 + const uint8_t *bytes; 77 + size_t len; 78 + ant_value_t callback; 79 + ant_value_t error; 80 + }; 81 + 64 82 static ant_value_t g_net_server_proto = 0; 65 83 static ant_value_t g_net_socket_proto = 0; 66 84 static ant_value_t g_net_server_ctor = 0; ··· 76 94 NET_SERVER_NATIVE_TAG = 0x4e455453u, 77 95 NET_SOCKET_NATIVE_TAG = 0x4e45544bu, 78 96 }; 97 + 98 + static ant_value_t net_not_implemented(ant_t *js, const char *what); 79 99 80 100 static net_server_t *net_server_data(ant_value_t value) { 81 101 if (!js_check_native_tag(value, NET_SERVER_NATIVE_TAG)) return NULL; ··· 135 155 return result; 136 156 } 137 157 138 - static ant_value_t net_call_method( 158 + static bool net_emit(ant_t *js, ant_value_t target, const char *event, ant_value_t *args, int nargs) { 159 + return eventemitter_emit_args(js, target, event, args, nargs); 160 + } 161 + 162 + static bool net_add_listener( 139 163 ant_t *js, 140 164 ant_value_t target, 141 - const char *name, 142 - ant_value_t *args, 143 - int nargs 165 + const char *event, 166 + ant_value_t listener, 167 + bool once 144 168 ) { 145 - ant_value_t fn = js_get(js, target, name); 146 - if (!is_callable(fn)) return js_mkundef(); 147 - return net_call_value(js, fn, target, args, nargs); 169 + return eventemitter_add_listener(js, target, event, listener, once); 170 + } 171 + 172 + static net_server_t *net_require_server(ant_t *js, ant_value_t this_val) { 173 + net_server_t *server = net_server_data(this_val); 174 + if (!server) { 175 + js->thrown_exists = true; 176 + js->thrown_value = js_mkerr_typed(js, JS_ERR_TYPE, "Invalid net.Server"); 177 + return NULL; 178 + } 179 + return server; 180 + } 181 + 182 + static net_socket_t *net_require_socket(ant_t *js, ant_value_t this_val) { 183 + net_socket_t *socket = net_socket_data(this_val); 184 + if (!socket) { 185 + js->thrown_exists = true; 186 + js->thrown_value = js_mkerr_typed(js, JS_ERR_TYPE, "Invalid net.Socket"); 187 + return NULL; 188 + } 189 + return socket; 190 + } 191 + 192 + static bool net_parse_write_args(ant_t *js, ant_value_t *args, int nargs, net_write_args_t *out) { 193 + ant_value_t value = 0; 194 + 195 + if (!out) return false; 196 + memset(out, 0, sizeof(*out)); 197 + out->callback = js_mkundef(); 198 + out->error = js_mkundef(); 199 + 200 + if (nargs < 1 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return true; 201 + value = args[0]; 202 + 203 + if (!buffer_source_get_bytes(js, value, &out->bytes, &out->len)) { 204 + size_t slen = 0; 205 + ant_value_t str_val = js_tostring_val(js, value); 206 + const char *str = NULL; 207 + 208 + if (is_err(str_val)) { 209 + out->error = str_val; 210 + return false; 211 + } 212 + 213 + str = js_getstr(js, str_val, &slen); 214 + if (!str) { 215 + out->error = js_mkerr_typed(js, JS_ERR_TYPE, "Invalid socket write data"); 216 + return false; 217 + } 218 + 219 + out->bytes = (const uint8_t *)str; 220 + out->len = slen; 221 + } 222 + 223 + if (nargs > 1 && is_callable(args[1])) out->callback = args[1]; 224 + else if (nargs > 2 && is_callable(args[2])) out->callback = args[2]; 225 + return true; 148 226 } 149 227 150 - static void net_emit(ant_t *js, ant_value_t target, const char *event, ant_value_t *args, int nargs) { 151 - ant_value_t emit_args[8] = {0}; 152 - int i = 0; 228 + static bool net_parse_listen_args(ant_t *js, ant_value_t *args, int nargs, net_listen_args_t *out) { 229 + if (!out) return false; 230 + 231 + memset(out, 0, sizeof(*out)); 232 + out->host = "0.0.0.0"; 233 + out->backlog = 511; 234 + out->callback = js_mkundef(); 235 + out->error = js_mkundef(); 153 236 154 - if (nargs > 7) nargs = 7; 155 - emit_args[0] = js_mkstr(js, event, strlen(event)); 156 - for (i = 0; i < nargs; i++) emit_args[i + 1] = args[i]; 157 - net_call_method(js, target, "emit", emit_args, nargs + 1); 237 + if (nargs == 0) return true; 238 + 239 + if (vtype(args[0]) == T_NUM) { 240 + out->port = (int)js_getnum(args[0]); 241 + if (nargs > 1 && vtype(args[1]) == T_STR) { 242 + size_t len = 0; 243 + out->host = js_getstr(js, args[1], &len); 244 + } 245 + if (nargs > 2 && vtype(args[2]) == T_NUM) out->backlog = (int)js_getnum(args[2]); 246 + if (nargs > 3 && is_callable(args[3])) out->callback = args[3]; 247 + else if (nargs > 2 && is_callable(args[2])) out->callback = args[2]; 248 + else if (nargs > 1 && is_callable(args[1])) out->callback = args[1]; 249 + return true; 250 + } 251 + 252 + if (vtype(args[0]) == T_OBJ) { 253 + ant_value_t value = js_get(js, args[0], "path"); 254 + if (vtype(value) != T_UNDEF) { 255 + out->error = net_not_implemented(js, "IPC server listen"); 256 + return false; 257 + } 258 + 259 + value = js_get(js, args[0], "port"); 260 + if (vtype(value) == T_NUM) out->port = (int)js_getnum(value); 261 + value = js_get(js, args[0], "host"); 262 + if (vtype(value) == T_STR) { 263 + size_t len = 0; 264 + out->host = js_getstr(js, value, &len); 265 + } 266 + value = js_get(js, args[0], "backlog"); 267 + if (vtype(value) == T_NUM) out->backlog = (int)js_getnum(value); 268 + if (nargs > 1 && is_callable(args[1])) out->callback = args[1]; 269 + return true; 270 + } 271 + 272 + if (vtype(args[0]) == T_STR) { 273 + out->error = net_not_implemented(js, "IPC server listen"); 274 + return false; 275 + } 276 + 277 + if (is_callable(args[0])) { 278 + out->callback = args[0]; 279 + return true; 280 + } 281 + 282 + return true; 158 283 } 159 284 160 285 static ant_value_t net_make_buffer_chunk(ant_t *js, const char *data, size_t len) { ··· 487 612 } 488 613 489 614 static ant_value_t js_net_socket_address(ant_t *js, ant_value_t *args, int nargs) { 490 - net_socket_t *socket = net_socket_data(js_getthis(js)); 615 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 491 616 ant_value_t out = js_mkobj(js); 492 617 618 + if (!socket) return js->thrown_value; 493 619 if (!socket || !socket->conn || !ant_conn_has_local_addr(socket->conn)) return out; 494 620 js_set(js, out, "address", js_mkstr(js, ant_conn_local_addr(socket->conn), strlen(ant_conn_local_addr(socket->conn)))); 495 621 js_set(js, out, "port", js_mknum(ant_conn_local_port(socket->conn))); ··· 498 624 } 499 625 500 626 static ant_value_t js_net_socket_pause(ant_t *js, ant_value_t *args, int nargs) { 501 - net_socket_t *socket = net_socket_data(js_getthis(js)); 627 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 628 + if (!socket) return js->thrown_value; 502 629 if (socket && socket->conn) ant_conn_pause_read(socket->conn); 503 630 return js_getthis(js); 504 631 } 505 632 506 633 static ant_value_t js_net_socket_resume(ant_t *js, ant_value_t *args, int nargs) { 507 - net_socket_t *socket = net_socket_data(js_getthis(js)); 634 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 635 + if (!socket) return js->thrown_value; 508 636 if (socket && socket->conn) ant_conn_resume_read(socket->conn); 509 637 return js_getthis(js); 510 638 } 511 639 512 640 static ant_value_t js_net_socket_setEncoding(ant_t *js, ant_value_t *args, int nargs) { 513 - net_socket_t *socket = net_socket_data(js_getthis(js)); 514 - if (!socket) return js_getthis(js); 641 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 642 + if (!socket) return js->thrown_value; 515 643 socket->encoding = nargs > 0 && vtype(args[0]) != T_UNDEF ? js_tostring_val(js, args[0]) : js_mkundef(); 516 644 return js_getthis(js); 517 645 } 518 646 519 647 static ant_value_t js_net_socket_setTimeout(ant_t *js, ant_value_t *args, int nargs) { 520 - net_socket_t *socket = net_socket_data(js_getthis(js)); 648 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 521 649 double timeout = 0; 522 - ant_value_t once_args[2] = {0}; 523 650 524 - if (!socket) return js_getthis(js); 651 + if (!socket) return js->thrown_value; 525 652 if (nargs > 0 && vtype(args[0]) == T_NUM) timeout = js_getnum(args[0]); 526 653 if (socket->conn) ant_conn_set_timeout_ms(socket->conn, timeout > 0 ? (uint64_t)timeout : 0); 527 654 net_socket_sync_state(socket); 528 655 529 - if (nargs > 1 && is_callable(args[1])) { 530 - once_args[0] = js_mkstr(js, "timeout", 7); 531 - once_args[1] = args[1]; 532 - net_call_method(js, socket->obj, "once", once_args, 2); 533 - } 656 + if (nargs > 1 && is_callable(args[1])) 657 + net_add_listener(js, socket->obj, "timeout", args[1], true); 534 658 535 659 return js_getthis(js); 536 660 } 537 661 538 662 static ant_value_t js_net_socket_setNoDelay(ant_t *js, ant_value_t *args, int nargs) { 539 - net_socket_t *socket = net_socket_data(js_getthis(js)); 663 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 540 664 bool enable = nargs == 0 || js_truthy(js, args[0]); 665 + if (!socket) return js->thrown_value; 541 666 if (socket && socket->conn) ant_conn_set_no_delay(socket->conn, enable); 542 667 return js_getthis(js); 543 668 } 544 669 545 670 static ant_value_t js_net_socket_setKeepAlive(ant_t *js, ant_value_t *args, int nargs) { 546 - net_socket_t *socket = net_socket_data(js_getthis(js)); 671 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 547 672 bool enable = nargs > 0 && js_truthy(js, args[0]); 548 673 unsigned int delay = nargs > 1 && vtype(args[1]) == T_NUM ? (unsigned int)(js_getnum(args[1]) / 1000.0) : 0; 674 + if (!socket) return js->thrown_value; 549 675 if (socket && socket->conn) ant_conn_set_keep_alive(socket->conn, enable, delay); 550 676 return js_getthis(js); 551 677 } 552 678 553 679 static ant_value_t js_net_socket_ref(ant_t *js, ant_value_t *args, int nargs) { 554 - net_socket_t *socket = net_socket_data(js_getthis(js)); 680 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 681 + if (!socket) return js->thrown_value; 555 682 if (socket && socket->conn) ant_conn_ref(socket->conn); 556 683 return js_getthis(js); 557 684 } 558 685 559 686 static ant_value_t js_net_socket_unref(ant_t *js, ant_value_t *args, int nargs) { 560 - net_socket_t *socket = net_socket_data(js_getthis(js)); 687 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 688 + if (!socket) return js->thrown_value; 561 689 if (socket && socket->conn) ant_conn_unref(socket->conn); 562 690 return js_getthis(js); 563 691 } 564 692 565 693 static ant_value_t js_net_socket_write(ant_t *js, ant_value_t *args, int nargs) { 566 - net_socket_t *socket = net_socket_data(js_getthis(js)); 567 - const uint8_t *bytes = NULL; 568 - size_t len = 0; 694 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 695 + net_write_args_t parsed; 569 696 char *copy = NULL; 570 697 571 - if (!socket || !socket->conn) return js_false; 572 - if (nargs < 1) return js_true; 573 - 574 - if (!buffer_source_get_bytes(js, args[0], &bytes, &len)) { 575 - size_t slen = 0; 576 - const char *str = js_getstr(js, js_tostring_val(js, args[0]), &slen); 577 - if (!str) return js_false; 578 - bytes = (const uint8_t *)str; 579 - len = slen; 580 - } 698 + if (!socket) return js->thrown_value; 699 + if (!socket->conn) return js_false; 700 + if (!net_parse_write_args(js, args, nargs, &parsed)) return parsed.error; 701 + if (parsed.len == 0) return js_true; 581 702 582 - copy = malloc(len); 703 + copy = malloc(parsed.len); 583 704 if (!copy) return js_mkerr_typed(js, JS_ERR_TYPE, "Out of memory"); 584 - if (len > 0) memcpy(copy, bytes, len); 705 + memcpy(copy, parsed.bytes, parsed.len); 585 706 586 - if (ant_conn_write(socket->conn, copy, len, NULL, NULL) != 0) { 707 + if (ant_conn_write(socket->conn, copy, parsed.len, NULL, NULL) != 0) { 587 708 free(copy); 588 709 return js_false; 589 710 } 590 711 591 712 net_socket_sync_state(socket); 592 - if (nargs > 2 && is_callable(args[2])) net_call_value(js, args[2], js_mkundef(), NULL, 0); 713 + if (is_callable(parsed.callback)) net_call_value(js, parsed.callback, js_mkundef(), NULL, 0); 593 714 return js_true; 594 715 } 595 716 596 717 static ant_value_t js_net_socket_end(ant_t *js, ant_value_t *args, int nargs) { 597 - net_socket_t *socket = net_socket_data(js_getthis(js)); 718 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 719 + net_write_args_t parsed; 598 720 ant_value_t result = js_getthis(js); 599 721 600 - if (!socket || !socket->conn) return result; 601 - if (nargs > 0 && vtype(args[0]) != T_UNDEF && vtype(args[0]) != T_NULL) 602 - js_net_socket_write(js, args, nargs); 722 + if (!socket) return js->thrown_value; 723 + if (!socket->conn) return result; 724 + if (!net_parse_write_args(js, args, nargs, &parsed)) return parsed.error; 725 + if (parsed.len > 0) { 726 + ant_value_t write_result = js_net_socket_write(js, args, nargs); 727 + if (is_err(write_result)) return write_result; 728 + } 603 729 ant_conn_shutdown(socket->conn); 604 - if (nargs > 2 && is_callable(args[2])) net_call_value(js, args[2], js_mkundef(), NULL, 0); 730 + if (is_callable(parsed.callback)) net_call_value(js, parsed.callback, js_mkundef(), NULL, 0); 605 731 return result; 606 732 } 607 733 608 734 static ant_value_t js_net_socket_destroy(ant_t *js, ant_value_t *args, int nargs) { 609 - net_socket_t *socket = net_socket_data(js_getthis(js)); 610 - if (!socket) return js_getthis(js); 735 + net_socket_t *socket = net_require_socket(js, js_getthis(js)); 736 + if (!socket) return js->thrown_value; 611 737 612 738 if (nargs > 0 && vtype(args[0]) != T_UNDEF && vtype(args[0]) != T_NULL) { 613 739 ant_value_t err = args[0]; ··· 625 751 626 752 static ant_value_t js_net_server_ctor(ant_t *js, ant_value_t *args, int nargs) { 627 753 net_server_t *server = net_server_create(js); 628 - ant_value_t on_args[2] = {0}; 629 754 630 755 if (!server) return js_mkerr_typed(js, JS_ERR_TYPE, "Out of memory"); 631 756 if (nargs > 0 && vtype(args[0]) == T_OBJ) net_server_apply_options(js, server, args[0]); 632 - if (nargs > 0 && is_callable(args[0])) { 633 - on_args[0] = js_mkstr(js, "connection", 10); 634 - on_args[1] = args[0]; 635 - net_call_method(js, server->obj, "on", on_args, 2); 636 - } else if (nargs > 1 && is_callable(args[1])) { 637 - on_args[0] = js_mkstr(js, "connection", 10); 638 - on_args[1] = args[1]; 639 - net_call_method(js, server->obj, "on", on_args, 2); 640 - } 757 + if (nargs > 0 && is_callable(args[0])) net_add_listener(js, server->obj, "connection", args[0], false); 758 + else if (nargs > 1 && is_callable(args[1])) net_add_listener(js, server->obj, "connection", args[1], false); 641 759 642 760 return server->obj; 643 761 } 644 762 645 763 static ant_value_t js_net_server_listen(ant_t *js, ant_value_t *args, int nargs) { 646 - net_server_t *server = net_server_data(js_getthis(js)); 764 + net_server_t *server = net_require_server(js, js_getthis(js)); 647 765 ant_listener_callbacks_t callbacks = {0}; 648 - const char *host = "0.0.0.0"; 649 - ant_value_t cb = js_mkundef(); 650 - int port = 0; 651 - int backlog = 511; 766 + net_listen_args_t parsed; 767 + const char *host = NULL; 652 768 int rc = 0; 653 769 654 - if (!server) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid net.Server"); 770 + if (!server) return js->thrown_value; 655 771 if (server->listening) return js_mkerr_typed(js, JS_ERR_TYPE, "Server is already listening"); 656 - 657 - if (nargs > 0 && vtype(args[0]) == T_NUM) { 658 - port = (int)js_getnum(args[0]); 659 - if (nargs > 1 && vtype(args[1]) == T_STR) { 660 - size_t len = 0; 661 - host = js_getstr(js, args[1], &len); 662 - } 663 - if (nargs > 2 && vtype(args[2]) == T_NUM) backlog = (int)js_getnum(args[2]); 664 - if (nargs > 3 && is_callable(args[3])) cb = args[3]; 665 - else if (nargs > 2 && is_callable(args[2])) cb = args[2]; 666 - else if (nargs > 1 && is_callable(args[1])) cb = args[1]; 667 - } else if (nargs > 0 && vtype(args[0]) == T_OBJ) { 668 - ant_value_t value = js_get(js, args[0], "path"); 669 - if (vtype(value) != T_UNDEF) return net_not_implemented(js, "IPC server listen"); 670 - 671 - value = js_get(js, args[0], "port"); 672 - if (vtype(value) == T_NUM) port = (int)js_getnum(value); 673 - value = js_get(js, args[0], "host"); 674 - if (vtype(value) == T_STR) { 675 - size_t len = 0; 676 - host = js_getstr(js, value, &len); 677 - } 678 - value = js_get(js, args[0], "backlog"); 679 - if (vtype(value) == T_NUM) backlog = (int)js_getnum(value); 680 - if (nargs > 1 && is_callable(args[1])) cb = args[1]; 681 - } else if (nargs > 0 && vtype(args[0]) == T_STR) { 682 - return net_not_implemented(js, "IPC server listen"); 683 - } else if (nargs > 0 && is_callable(args[0])) { 684 - cb = args[0]; 685 - } 772 + if (!net_parse_listen_args(js, args, nargs, &parsed)) return parsed.error; 686 773 774 + host = parsed.host; 687 775 net_server_parse_host(host, &host); 688 776 free(server->host); 689 777 server->host = strdup(host ? host : "0.0.0.0"); 690 - server->port = port; 691 - server->backlog = backlog > 0 ? backlog : server->backlog; 778 + server->port = parsed.port; 779 + server->backlog = parsed.backlog > 0 ? parsed.backlog : server->backlog; 692 780 693 781 callbacks.on_accept = net_server_on_accept; 694 782 callbacks.on_read = net_socket_on_read; ··· 702 790 &server->listener, 703 791 uv_default_loop(), 704 792 server->host, 705 - port, 793 + parsed.port, 706 794 server->backlog, 707 795 0, 708 796 &callbacks, ··· 716 804 net_server_sync_state(server); 717 805 net_add_active_server(server); 718 806 719 - if (is_callable(cb)) net_call_value(js, cb, js_mkundef(), NULL, 0); 807 + if (is_callable(parsed.callback)) net_call_value(js, parsed.callback, js_mkundef(), NULL, 0); 720 808 net_emit(js, server->obj, "listening", NULL, 0); 721 809 return js_getthis(js); 722 810 } 723 811 724 812 static ant_value_t js_net_server_close(ant_t *js, ant_value_t *args, int nargs) { 725 - net_server_t *server = net_server_data(js_getthis(js)); 726 - ant_value_t once_args[2] = {0}; 813 + net_server_t *server = net_require_server(js, js_getthis(js)); 727 814 728 - if (!server) return js_getthis(js); 815 + if (!server) return js->thrown_value; 729 816 730 - if (nargs > 0 && is_callable(args[0])) { 731 - once_args[0] = js_mkstr(js, "close", 5); 732 - once_args[1] = args[0]; 733 - net_call_method(js, server->obj, "once", once_args, 2); 734 - } 817 + if (nargs > 0 && is_callable(args[0])) net_add_listener(js, server->obj, "close", args[0], true); 735 818 736 819 if (!server->listening && !server->closing) { 737 820 if (nargs > 0 && is_callable(args[0])) { ··· 748 831 } 749 832 750 833 static ant_value_t js_net_server_address(ant_t *js, ant_value_t *args, int nargs) { 751 - net_server_t *server = net_server_data(js_getthis(js)); 834 + net_server_t *server = net_require_server(js, js_getthis(js)); 752 835 ant_value_t out = js_mknull(); 836 + if (!server) return js->thrown_value; 753 837 if (!server || !server->listening) return out; 754 838 755 839 out = js_mkobj(js); ··· 760 844 } 761 845 762 846 static ant_value_t js_net_server_getConnections(ant_t *js, ant_value_t *args, int nargs) { 763 - net_server_t *server = net_server_data(js_getthis(js)); 847 + net_server_t *server = net_require_server(js, js_getthis(js)); 764 848 ant_value_t cb = nargs > 0 ? args[0] : js_mkundef(); 765 849 ant_value_t argv[2] = { js_mknull(), js_mknum((double)net_server_socket_count(server)) }; 766 850 851 + if (!server) return js->thrown_value; 767 852 if (is_callable(cb)) net_call_value(js, cb, js_mkundef(), argv, 2); 768 853 return js_getthis(js); 769 854 } 770 855 771 856 static ant_value_t js_net_server_ref(ant_t *js, ant_value_t *args, int nargs) { 772 - net_server_t *server = net_server_data(js_getthis(js)); 857 + net_server_t *server = net_require_server(js, js_getthis(js)); 858 + if (!server) return js->thrown_value; 773 859 if (server && !uv_is_closing((uv_handle_t *)&server->listener.handle)) 774 860 uv_ref((uv_handle_t *)&server->listener.handle); 775 861 return js_getthis(js); 776 862 } 777 863 778 864 static ant_value_t js_net_server_unref(ant_t *js, ant_value_t *args, int nargs) { 779 - net_server_t *server = net_server_data(js_getthis(js)); 865 + net_server_t *server = net_require_server(js, js_getthis(js)); 866 + if (!server) return js->thrown_value; 780 867 if (server && !uv_is_closing((uv_handle_t *)&server->listener.handle)) 781 868 uv_unref((uv_handle_t *)&server->listener.handle); 782 869 return js_getthis(js);