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.

implement emitter registry for per-emitter event tracking

+74 -13
+19
examples/demo/ephemeral_server.js
··· 1 + let count = 0; 2 + 3 + console.log('starting on http://localhost:3000'); 4 + 5 + Ant.serve(3000, (ctx, server) => { 6 + if (ctx.req.uri.includes('favicon')) return; 7 + 8 + count++; 9 + ctx.res.json({ 10 + request: count, 11 + remaining: 10 - count, 12 + port: server.port 13 + }); 14 + 15 + if (count >= 10) { 16 + console.log('10 requests served, stopping'); 17 + server.stop(); 18 + } 19 + });
+17
src/modules/events.c
··· 20 20 bool once; 21 21 } __attribute__((packed)) EventListener; 22 22 23 + 23 24 typedef struct { 24 25 EventListener listeners[MAX_LISTENERS_PER_EVENT]; 25 26 char *event_type; ··· 27 28 int listener_count; 28 29 } EventType; 29 30 31 + typedef struct emitter_reg { 32 + EventType **events; 33 + struct emitter_reg *next; 34 + } emitter_reg_t; 35 + 30 36 static EventType *global_events = NULL; 37 + static emitter_reg_t *emitter_registry = NULL; 31 38 32 39 static inline void remove_listener_at(EventType *evt, int i) { 33 40 int remaining = evt->listener_count - i - 1; ··· 44 51 EventType **events = ant_calloc(sizeof(EventType *)); 45 52 if (!events) return NULL; 46 53 *events = NULL; 54 + emitter_reg_t *reg = ant_calloc(sizeof(emitter_reg_t)); 55 + if (reg) { 56 + reg->events = events; 57 + reg->next = emitter_registry; 58 + emitter_registry = reg; 59 + } 47 60 js_set_slot(js, this_obj, SLOT_DATA, ANT_PTR(events)); 48 61 return events; 49 62 } ··· 596 609 EventType *evt, *tmp; 597 610 HASH_ITER(hh, global_events, evt, tmp) { 598 611 for (int i = 0; i < evt->listener_count; i++) op_val(ctx, &evt->listeners[i].listener); 612 + } 613 + for (emitter_reg_t *reg = emitter_registry; reg; reg = reg->next) { 614 + HASH_ITER(hh, *reg->events, evt, tmp) 615 + for (int i = 0; i < evt->listener_count; i++) op_val(ctx, &evt->listeners[i].listener); 599 616 } 600 617 }
+31 -10
src/modules/server.c
··· 76 76 struct js *js; 77 77 jsval_t handler; 78 78 jsval_t store_obj; 79 + jsval_t server_obj; 79 80 int port; 80 81 uv_tcp_t server; 81 82 uv_loop_t *loop; ··· 97 98 } write_req_t; 98 99 99 100 static http_server_t *g_server = NULL; 100 - static uv_async_t shutdown_async; 101 + static uv_signal_t sigint_handle; 102 + static uv_signal_t sigterm_handle; 101 103 102 - static void shutdown_async_cb(uv_async_t *handle) { uv_stop(uv_default_loop()); } 103 - static void server_signal_handler(int signum) { uv_async_send(&shutdown_async); } 104 + static void server_signal_cb(uv_signal_t *handle, int signum) { 105 + if (g_server) uv_close((uv_handle_t *)&g_server->server, NULL); 106 + uv_close((uv_handle_t *)&sigint_handle, NULL); 107 + uv_close((uv_handle_t *)&sigterm_handle, NULL); 108 + uv_stop(uv_default_loop()); 109 + } 104 110 105 111 static int parse_accept_encoding(const char *buffer, size_t len) { 106 112 const char *accept_encoding = strstr(buffer, "Accept-Encoding:"); ··· 685 691 uv_write((uv_write_t *)write_req, client, &write_req->buf, 1, on_write); 686 692 } 687 693 694 + static jsval_t js_server_stop(struct js *js, jsval_t *args, int nargs) { 695 + server_signal_cb(NULL, 0); 696 + return js_mkundef(); 697 + } 698 + 688 699 static void handle_http_request(client_t *client, http_request_t *http_req) { 689 700 http_server_t *server = client->server; 690 701 jsval_t result = js_mkundef(); ··· 737 748 js_set(server->js, ctx, "set", js_heavy_mkfun(server->js, js_set_prop, server->store_obj)); 738 749 js_set(server->js, ctx, "get", js_heavy_mkfun(server->js, js_get_prop, server->store_obj)); 739 750 740 - jsval_t args[1] = {ctx}; 741 - result = js_call(server->js, server->handler, args, 1); 751 + jsval_t args[2] = {ctx, server->server_obj}; 752 + result = js_call(server->js, server->handler, args, 2); 742 753 if (vtype(result) == T_PROMISE) return; 743 754 744 755 if (vtype(result) == T_ERR) { ··· 931 942 932 943 server->store_obj = js_mkobj(js); 933 944 server->handler = (nargs >= 2) ? args[1] : js_mkundef(); 945 + 946 + jsval_t server_obj = js_mkobj(js); 947 + js_set(js, server_obj, "stop", js_mkfun(js_server_stop)); 948 + js_set(js, server_obj, "port", js_mknum(port)); 949 + 950 + server->server_obj = server_obj; 934 951 g_server = server; 935 952 936 953 uv_loop_t *loop = uv_default_loop(); 937 954 server->loop = loop; 938 955 939 - uv_async_init(loop, 940 - &shutdown_async, shutdown_async_cb 941 - ); 956 + uv_signal_init(loop, &sigint_handle); 957 + uv_signal_init(loop, &sigterm_handle); 942 958 943 - signal(SIGINT, server_signal_handler); 944 - signal(SIGTERM, server_signal_handler); 959 + uv_signal_start(&sigint_handle, server_signal_cb, SIGINT); 960 + uv_signal_start(&sigterm_handle, server_signal_cb, SIGTERM); 945 961 946 962 uv_tcp_init(loop, &server->server); 947 963 server->server.data = server; ··· 973 989 ); 974 990 975 991 js_run_event_loop(js); 992 + js_reactor_set_poll_hook(NULL, NULL); 976 993 js_gc_throttle(false); 994 + 995 + free(server); 996 + g_server = NULL; 977 997 978 998 return js_mknum(1); 979 999 } ··· 986 1006 if (g_server) { 987 1007 op_val(ctx, &g_server->handler); 988 1008 op_val(ctx, &g_server->store_obj); 1009 + op_val(ctx, &g_server->server_obj); 989 1010 } 990 1011 }
+6 -2
src/modules/url.c
··· 9 9 #include "errors.h" 10 10 #include "internal.h" 11 11 #include "runtime.h" 12 + #include "utils.h" 13 + 12 14 #include "modules/url.h" 13 15 #include "modules/symbol.h" 14 16 ··· 448 450 jsoff_t len = js_arr_len(js, entries); 449 451 450 452 size_t buf_size = 1024; 451 - char *buf = malloc(buf_size); 453 + char *buf = try_oom(buf_size); 452 454 buf[0] = '?'; 453 455 size_t pos = 1; 454 456 ··· 465 467 if (pos + needed >= buf_size) { 466 468 buf_size = buf_size * 2 + needed; 467 469 buf = realloc(buf, buf_size); 470 + if (!buf) { free(buf); return; } 468 471 } 469 472 470 473 if (pos > 1) buf[pos++] = '&'; ··· 561 564 jsoff_t len = js_arr_len(js, entries); 562 565 563 566 size_t buf_size = 1024; 564 - char *buf = malloc(buf_size); 567 + char *buf = try_oom(buf_size); 565 568 size_t pos = 0; 566 569 567 570 for (jsoff_t i = 0; i < len; i++) { ··· 577 580 if (pos + needed >= buf_size) { 578 581 buf_size = buf_size * 2 + needed; 579 582 buf = realloc(buf, buf_size); 583 + if (!buf) { free(buf); return js_mkstr(js, "", 0); } 580 584 } 581 585 582 586 if (pos > 0) buf[pos++] = '&';
+1 -1
tests/bench_array_create.js
··· 34 34 function create_prealloc_push() { 35 35 var tab = []; 36 36 tab.length = 1000; 37 - for (var i = 0; i < 1000; i++) tab[i] = i; 37 + for (var i = 0; i < 1000; i++) tab.push(i); 38 38 } 39 39 40 40 function main() {