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.

add garbage collection support to modules

+100 -122
+8 -9
src/ant.c
··· 2044 2044 if (e->hash == h && e->len == len && memcmp(e->str, str, len) == 0) return e->str; 2045 2045 } 2046 2046 2047 - interned_string_t *entry = (interned_string_t *)malloc(sizeof(interned_string_t)); 2047 + interned_string_t *entry = (interned_string_t *)ANT_GC_MALLOC(sizeof(interned_string_t) + len + 1); 2048 2048 if (!entry) return NULL; 2049 - entry->str = (char *)malloc(len + 1); 2050 - if (!entry->str) { free(entry); return NULL; } 2051 2049 2050 + entry->str = (char *)(entry + 1); 2052 2051 memcpy(entry->str, str, len); 2053 2052 entry->str[len] = '\0'; 2054 2053 entry->len = len; ··· 22060 22059 descriptor_entry_t *entry = NULL; 22061 22060 HASH_FIND(hh, desc_registry, &desc_key, sizeof(uint64_t), entry); 22062 22061 if (!entry) { 22063 - entry = (descriptor_entry_t *)malloc(sizeof(descriptor_entry_t)); 22062 + entry = (descriptor_entry_t *)ANT_GC_MALLOC(sizeof(descriptor_entry_t) + klen + 1); 22064 22063 if (!entry) return NULL; 22064 + 22065 22065 entry->key = desc_key; 22066 22066 entry->obj_off = obj_off; 22067 - entry->prop_name = (char *)malloc(klen + 1); 22068 - if (entry->prop_name) { 22069 - memcpy(entry->prop_name, key, klen); 22070 - entry->prop_name[klen] = '\0'; 22071 - } 22067 + entry->prop_name = (char *)(entry + 1); 22068 + memcpy(entry->prop_name, key, klen); 22069 + entry->prop_name[klen] = '\0'; 22072 22070 entry->prop_len = klen; 22073 22071 entry->writable = true; 22074 22072 entry->enumerable = true; ··· 22077 22075 entry->has_setter = false; 22078 22076 entry->getter = js_mkundef(); 22079 22077 entry->setter = js_mkundef(); 22078 + 22080 22079 HASH_ADD(hh, desc_registry, key, sizeof(uint64_t), entry); 22081 22080 } 22082 22081 return entry;
+4 -2
src/gc.c
··· 49 49 50 50 static void fwd_add(gc_forward_table_t *fwd, jsoff_t old_off, jsoff_t new_off) { 51 51 size_t h = fwd_hash(old_off); 52 - gc_forward_node_t *node = malloc(sizeof(gc_forward_node_t)); 52 + gc_forward_node_t *node = ANT_GC_MALLOC(sizeof(gc_forward_node_t)); 53 53 node->old_off = old_off; 54 54 node->new_off = new_off; 55 55 node->next = fwd->buckets[h]; ··· 69 69 gc_forward_node_t *n = fwd->buckets[i]; 70 70 while (n) { 71 71 gc_forward_node_t *next = n->next; 72 - free(n); n = next; 72 + ANT_GC_FREE(n); 73 + n = next; 73 74 } 75 + fwd->buckets[i] = NULL; 74 76 } 75 77 } 76 78
+8 -11
src/modules/buffer.c
··· 9 9 #include <sys/mman.h> 10 10 #endif 11 11 12 + #include "ant.h" 13 + #include "arena.h" 12 14 #include "runtime.h" 15 + 13 16 #include "modules/buffer.h" 14 17 #include "modules/symbol.h" 15 18 ··· 123 126 } 124 127 125 128 static ArrayBufferData *create_array_buffer_data(size_t length) { 126 - ArrayBufferData *data = malloc(sizeof(ArrayBufferData)); 129 + ArrayBufferData *data = ANT_GC_MALLOC(sizeof(ArrayBufferData) + length); 127 130 if (!data) return NULL; 128 131 129 - data->data = calloc(length, 1); 130 - if (!data->data && length > 0) { 131 - free(data); 132 - return NULL; 133 - } 132 + data->data = (uint8_t *)(data + 1); 133 + memset(data->data, 0, length); 134 134 135 135 data->length = length; 136 136 data->capacity = length; ··· 148 148 static void free_array_buffer_data(ArrayBufferData *data) { 149 149 if (!data) return; 150 150 data->ref_count--; 151 - if (data->ref_count <= 0) { 152 - free(data->data); 153 - free(data); 154 - } 151 + if (data->ref_count <= 0) ANT_GC_FREE(data); 155 152 } 156 153 157 154 static size_t get_element_size(TypedArrayType type) { ··· 573 570 byte_length = buffer->length - byte_offset; 574 571 } 575 572 576 - DataViewData *dv_data = malloc(sizeof(DataViewData)); 573 + DataViewData *dv_data = ANT_GC_MALLOC(sizeof(DataViewData)); 577 574 if (!dv_data) return js_mkerr(js, "Failed to allocate DataView"); 578 575 579 576 dv_data->buffer = buffer;
+15 -9
src/modules/events.c
··· 2 2 #include <stdio.h> 3 3 #include <string.h> 4 4 #include <inttypes.h> 5 + #include <uthash.h> 5 6 6 7 #include "ant.h" 8 + #include "arena.h" 7 9 #include "runtime.h" 10 + 8 11 #include "modules/events.h" 9 12 #include "modules/symbol.h" 10 - #include "uthash.h" 11 13 12 14 #define MAX_LISTENERS_PER_EVENT 32 13 15 ··· 39 41 HASH_FIND(hh, target_events_map, &target_id, sizeof(uint64_t), te); 40 42 41 43 if (te == NULL) { 42 - te = malloc(sizeof(TargetEvents)); 44 + te = ANT_GC_MALLOC(sizeof(TargetEvents)); 43 45 te->target_id = target_id; 44 46 te->events = NULL; 45 47 HASH_ADD(hh, target_events_map, target_id, sizeof(uint64_t), te); ··· 57 59 emitter_id = next_emitter_id++; 58 60 js_set(js, this_obj, "_emitter_id", js_mknum((double)emitter_id)); 59 61 60 - te = malloc(sizeof(TargetEvents)); 62 + te = ANT_GC_MALLOC(sizeof(TargetEvents)); 61 63 te->target_id = emitter_id; 62 64 te->events = NULL; 63 65 HASH_ADD(hh, target_events_map, target_id, sizeof(uint64_t), te); ··· 86 88 HASH_FIND_STR(te->events, event_type, evt); 87 89 88 90 if (evt == NULL) { 89 - evt = malloc(sizeof(EventType)); 90 - evt->event_type = strdup(event_type); 91 + size_t etlen = strlen(event_type); 92 + evt = ANT_GC_MALLOC(sizeof(EventType) + etlen + 1); 93 + evt->event_type = (char *)(evt + 1); 94 + memcpy(evt->event_type, event_type, etlen + 1); 91 95 evt->listener_count = 0; 92 - HASH_ADD_KEYPTR(hh, te->events, evt->event_type, strlen(evt->event_type), evt); 96 + HASH_ADD_KEYPTR(hh, te->events, evt->event_type, etlen, evt); 93 97 } 94 98 95 99 return evt; ··· 102 106 HASH_FIND_STR(te->events, event_type, evt); 103 107 104 108 if (evt == NULL) { 105 - evt = malloc(sizeof(EventType)); 106 - evt->event_type = strdup(event_type); 109 + size_t etlen = strlen(event_type); 110 + evt = ANT_GC_MALLOC(sizeof(EventType) + etlen + 1); 111 + evt->event_type = (char *)(evt + 1); 112 + memcpy(evt->event_type, event_type, etlen + 1); 107 113 evt->listener_count = 0; 108 - HASH_ADD_KEYPTR(hh, te->events, evt->event_type, strlen(evt->event_type), evt); 114 + HASH_ADD_KEYPTR(hh, te->events, evt->event_type, etlen, evt); 109 115 } 110 116 111 117 return evt;
+24 -43
src/modules/localstorage.c
··· 4 4 #include <uthash.h> 5 5 #include <yyjson.h> 6 6 7 + #include "ant.h" 8 + #include "arena.h" 7 9 #include "runtime.h" 8 - #include "modules/localstorage.h" 10 + 9 11 #include "modules/symbol.h" 12 + #include "modules/localstorage.h" 10 13 11 14 typedef struct storage_entry { 12 15 char *key; ··· 61 64 size_t klen = yyjson_get_len(key); 62 65 size_t vlen = yyjson_get_len(val); 63 66 64 - storage_entry_t *entry = malloc(sizeof(storage_entry_t)); 67 + storage_entry_t *entry = ANT_GC_MALLOC(sizeof(storage_entry_t) + klen + 1 + vlen + 1); 65 68 if (!entry) continue; 66 69 67 - entry->key = malloc(klen + 1); 68 - entry->value = malloc(vlen + 1); 69 - 70 - if (!entry->key || !entry->value) { 71 - free(entry->key); 72 - free(entry->value); 73 - free(entry); 74 - continue; 75 - } 70 + entry->key = (char *)(entry + 1); 71 + entry->value = entry->key + klen + 1; 76 72 77 73 memcpy(entry->key, k, klen); 78 74 entry->key[klen] = '\0'; ··· 90 86 storage_entry_t *entry, *tmp; 91 87 HASH_ITER(hh, local_storage, entry, tmp) { 92 88 HASH_DEL(local_storage, entry); 93 - free(entry->key); 94 - free(entry->value); 95 - free(entry); 89 + ANT_GC_FREE(entry); 96 90 } 97 91 } 98 92 ··· 102 96 HASH_FIND(hh, local_storage, key, key_len, entry); 103 97 104 98 if (entry) { 105 - free(entry->value); 106 - entry->value = malloc(value_len + 1); 107 - if (entry->value) { 108 - memcpy(entry->value, value, value_len); 109 - entry->value[value_len] = '\0'; 110 - } 111 - } else { 112 - entry = malloc(sizeof(storage_entry_t)); 113 - if (!entry) return; 114 - 115 - entry->key = malloc(key_len + 1); 116 - entry->value = malloc(value_len + 1); 117 - 118 - if (!entry->key || !entry->value) { 119 - free(entry->key); 120 - free(entry->value); 121 - free(entry); 122 - return; 123 - } 124 - 125 - memcpy(entry->key, key, key_len); 126 - entry->key[key_len] = '\0'; 127 - memcpy(entry->value, value, value_len); 128 - entry->value[value_len] = '\0'; 129 - 130 - HASH_ADD_KEYPTR(hh, local_storage, entry->key, key_len, entry); 99 + HASH_DEL(local_storage, entry); 100 + ANT_GC_FREE(entry); 131 101 } 132 102 103 + entry = ANT_GC_MALLOC(sizeof(storage_entry_t) + key_len + 1 + value_len + 1); 104 + if (!entry) return; 105 + 106 + entry->key = (char *)(entry + 1); 107 + entry->value = entry->key + key_len + 1; 108 + 109 + memcpy(entry->key, key, key_len); 110 + entry->key[key_len] = '\0'; 111 + memcpy(entry->value, value, value_len); 112 + entry->value[value_len] = '\0'; 113 + 114 + HASH_ADD_KEYPTR(hh, local_storage, entry->key, key_len, entry); 115 + 133 116 storage_save(); 134 117 } 135 118 ··· 145 128 146 129 if (entry) { 147 130 HASH_DEL(local_storage, entry); 148 - free(entry->key); 149 - free(entry->value); 150 - free(entry); 131 + ANT_GC_FREE(entry); 151 132 storage_save(); 152 133 } 153 134 }
+28 -40
src/modules/sessionstorage.c
··· 2 2 #include <string.h> 3 3 #include <uthash.h> 4 4 5 + #include "ant.h" 6 + #include "arena.h" 5 7 #include "runtime.h" 6 - #include "modules/sessionstorage.h" 8 + 7 9 #include "modules/symbol.h" 10 + #include "modules/sessionstorage.h" 8 11 9 12 typedef struct storage_entry { 10 13 char *key; ··· 14 17 15 18 static storage_entry_t *session_storage = NULL; 16 19 17 - static void storage_clear(void) { 18 - storage_entry_t *entry, *tmp; 19 - HASH_ITER(hh, session_storage, entry, tmp) { 20 - HASH_DEL(session_storage, entry); 21 - free(entry->key); 22 - free(entry->value); 23 - free(entry); 24 - } 25 - } 26 - 27 20 static void storage_set_item(const char *key, size_t key_len, const char *value, size_t value_len) { 28 21 storage_entry_t *entry = NULL; 29 22 30 23 HASH_FIND(hh, session_storage, key, key_len, entry); 31 24 32 25 if (entry) { 33 - free(entry->value); 34 - entry->value = malloc(value_len + 1); 35 - if (entry->value) { 36 - memcpy(entry->value, value, value_len); 37 - entry->value[value_len] = '\0'; 38 - } 39 - } else { 40 - entry = malloc(sizeof(storage_entry_t)); 41 - if (!entry) return; 42 - 43 - entry->key = malloc(key_len + 1); 44 - entry->value = malloc(value_len + 1); 45 - 46 - if (!entry->key || !entry->value) { 47 - free(entry->key); 48 - free(entry->value); 49 - free(entry); 50 - return; 51 - } 52 - 53 - memcpy(entry->key, key, key_len); 54 - entry->key[key_len] = '\0'; 55 - memcpy(entry->value, value, value_len); 56 - entry->value[value_len] = '\0'; 57 - 58 - HASH_ADD_KEYPTR(hh, session_storage, entry->key, key_len, entry); 26 + HASH_DEL(session_storage, entry); 27 + ANT_GC_FREE(entry); 59 28 } 29 + 30 + entry = ANT_GC_MALLOC(sizeof(storage_entry_t) + key_len + 1 + value_len + 1); 31 + if (!entry) return; 32 + 33 + entry->key = (char *)(entry + 1); 34 + entry->value = entry->key + key_len + 1; 35 + 36 + memcpy(entry->key, key, key_len); 37 + entry->key[key_len] = '\0'; 38 + memcpy(entry->value, value, value_len); 39 + entry->value[value_len] = '\0'; 40 + 41 + HASH_ADD_KEYPTR(hh, session_storage, entry->key, key_len, entry); 60 42 } 61 43 62 44 static char *storage_get_item(const char *key, size_t key_len) { ··· 71 53 72 54 if (entry) { 73 55 HASH_DEL(session_storage, entry); 74 - free(entry->key); 75 - free(entry->value); 76 - free(entry); 56 + ANT_GC_FREE(entry); 57 + } 58 + } 59 + 60 + static void storage_clear(void) { 61 + storage_entry_t *entry, *tmp; 62 + HASH_ITER(hh, session_storage, entry, tmp) { 63 + HASH_DEL(session_storage, entry); 64 + ANT_GC_FREE(entry); 77 65 } 78 66 } 79 67
+13 -8
src/modules/timer.c
··· 4 4 #include <stdlib.h> 5 5 #include <string.h> 6 6 #include <time.h> 7 + 7 8 #ifdef _WIN32 8 9 #include <windows.h> 9 10 #else 10 11 #include <sys/time.h> 11 12 #endif 12 13 14 + #include "arena.h" 13 15 #include "runtime.h" 14 16 #include "modules/timer.h" 15 17 ··· 72 74 return js_mkerr(js, "setTimeout delay must be non-negative"); 73 75 } 74 76 75 - timer_entry_t *entry = malloc(sizeof(timer_entry_t)); 77 + timer_entry_t *entry = ANT_GC_MALLOC(sizeof(timer_entry_t)); 76 78 if (entry == NULL) { 77 79 return js_mkerr(js, "failed to allocate timer"); 78 80 } ··· 102 104 return js_mkerr(js, "setInterval delay must be non-negative"); 103 105 } 104 106 105 - timer_entry_t *entry = malloc(sizeof(timer_entry_t)); 107 + timer_entry_t *entry = ANT_GC_MALLOC(sizeof(timer_entry_t)); 106 108 if (entry == NULL) { 107 109 return js_mkerr(js, "failed to allocate timer"); 108 110 } ··· 145 147 146 148 jsval_t callback = args[0]; 147 149 148 - immediate_entry_t *entry = malloc(sizeof(immediate_entry_t)); 150 + immediate_entry_t *entry = ANT_GC_MALLOC(sizeof(immediate_entry_t)); 149 151 if (entry == NULL) { 150 152 return js_mkerr(js, "failed to allocate immediate"); 151 153 } ··· 189 191 } 190 192 191 193 void queue_microtask(struct js *js, jsval_t callback) { 192 - microtask_entry_t *entry = malloc(sizeof(microtask_entry_t)); 194 + microtask_entry_t *entry = ANT_GC_MALLOC(sizeof(microtask_entry_t)); 193 195 if (entry == NULL) return; 194 196 195 197 entry->callback = callback; ··· 216 218 jsval_t args[0]; 217 219 js_call(js, entry->callback, args, 0); 218 220 219 - free(entry); 221 + ANT_GC_FREE(entry); 220 222 } 221 223 } 222 224 ··· 235 237 process_microtasks(js); 236 238 } 237 239 238 - free(entry); 240 + ANT_GC_FREE(entry); 239 241 } 240 242 } 241 243 ··· 252 254 253 255 scan: 254 256 if (!*ptr) return; 255 - if (*ptr == target) { *ptr = target->next; free(target); return; } 257 + if (*ptr == target) { 258 + *ptr = target->next; 259 + ANT_GC_FREE(target); return; 260 + } 256 261 ptr = &(*ptr)->next; 257 262 goto scan; 258 263 } ··· 268 273 269 274 if (!entry->active) { 270 275 *ptr = entry->next; 271 - free(entry); 276 + ANT_GC_FREE(entry); 272 277 goto scan; 273 278 } 274 279