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.

snapshots for modules

+309 -3
+1
.gitignore
··· 1 1 .nova 2 2 .cache 3 + .env 3 4 4 5 /build 5 6 /subprojects/*/
+9
include/snapshot.h
··· 1 + #ifndef ANT_SNAPSHOT_LOADER_H 2 + #define ANT_SNAPSHOT_LOADER_H 3 + 4 + #include "ant.h" 5 + 6 + jsval_t ant_load_snapshot(struct js *js); 7 + const char *ant_get_snapshot_source(size_t *len); 8 + 9 + #endif
+41 -2
meson.build
··· 15 15 'src/ant.c', 16 16 'src/repl.c', 17 17 'src/runtime.c', 18 + 'src/snapshot.c', 18 19 ) + files(module_files) 19 20 20 21 # system dependencies ··· 43 44 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 44 45 45 46 version_conf = configuration_data() 46 - version_conf.set('ANT_VERSION', '0.0.6.13') 47 + version_conf.set('ANT_VERSION', '0.0.6.14') 47 48 version_conf.set('ANT_GIT_HASH', git_hash) 48 49 version_conf.set('ANT_BUILD_DATE', build_date) 49 50 ··· 56 57 build_include = include_directories('.') 57 58 add_project_arguments('-D JS_DUMP', language: 'c') 58 59 60 + gen_snapshot_sources = files( 61 + 'src/ant.c', 62 + 'src/runtime.c', 63 + 'src/tools/gen_snapshot.c', 64 + ) + files(module_files) 65 + 66 + gen_snapshot = executable( 67 + 'gen_snapshot', 68 + gen_snapshot_sources, 69 + include_directories: [include, build_include], 70 + dependencies: [ 71 + curl_dep, 72 + yyjson_dep, 73 + uuidv7_dep, 74 + mongoose_dep, 75 + argtable3_dep, 76 + libsodium_dep, 77 + minicoro_dep 78 + ], 79 + c_args: ['-DANT_SNAPSHOT_GENERATOR'], 80 + native: true 81 + ) 82 + 83 + snapshot_h = custom_target( 84 + 'snapshot', 85 + input: 'src/core/index.js', 86 + output: 'snapshot_data.h', 87 + command: [ 88 + gen_snapshot, 89 + '@INPUT@', 90 + '@OUTPUT@', 91 + 'VERSION=' + version_conf.get('ANT_VERSION'), 92 + 'GIT_HASH=' + version_conf.get('ANT_GIT_HASH'), 93 + 'BUILD_DATE=' + version_conf.get('ANT_BUILD_DATE') 94 + ], 95 + build_by_default: true 96 + ) 97 + 59 98 executable( 60 99 'ant', 61 - sources, 100 + sources + [snapshot_h], 62 101 include_directories: [include, build_include], 63 102 dependencies: [ 64 103 curl_dep,
+3
src/core/index.js
··· 1 + Ant.version = '{{VERSION}}'; 2 + Ant.revision = '{{GIT_HASH}}'; 3 + Ant.buildDate = '{{BUILD_DATE}}';
+13 -1
src/runtime.c
··· 1 + #ifndef ANT_SNAPSHOT_GENERATOR 2 + #include "snapshot.h" 3 + #endif 4 + 1 5 #include <stdio.h> 2 6 #include <stdlib.h> 3 - #include "runtime.h" 7 + #include <runtime.h> 4 8 5 9 static struct ant_runtime runtime = {0}; 6 10 ··· 12 16 runtime.crypto_initialized = 0; 13 17 14 18 js_set(js, js_glob(js), "Ant", runtime.ant_obj); 19 + 20 + #ifndef ANT_SNAPSHOT_GENERATOR 21 + jsval_t snapshot_result = ant_load_snapshot(js); 22 + if (js_type(snapshot_result) == JS_ERR) { 23 + fprintf(stderr, "Warning: Failed to load snapshot: %s\n", js_str(js, snapshot_result)); 24 + } 25 + #endif 26 + 15 27 return &runtime; 16 28 }
+18
src/snapshot.c
··· 1 + #include <string.h> 2 + 3 + #include "ant.h" 4 + #include "snapshot.h" 5 + #include "snapshot_data.h" 6 + 7 + jsval_t ant_load_snapshot(struct js *js) { 8 + if (!js) return js_mkerr(js, "invalid js runtime"); 9 + jsval_t result = js_eval(js, ant_snapshot_source, ant_snapshot_source_len); 10 + 11 + if (js_type(result) == JS_ERR) return result; 12 + return js_mktrue(); 13 + } 14 + 15 + const char *ant_get_snapshot_source(size_t *len) { 16 + if (len) *len = ant_snapshot_source_len; 17 + return ant_snapshot_source; 18 + }
+224
src/tools/gen_snapshot.c
··· 1 + #include <stdio.h> 2 + #include <stdlib.h> 3 + #include <string.h> 4 + 5 + #include "ant.h" 6 + #include "runtime.h" 7 + 8 + typedef struct { 9 + char *placeholder; 10 + char *value; 11 + } replacement_t; 12 + 13 + static char *replace_templates(const char *input, size_t input_len, replacement_t *replacements, int num_replacements, size_t *output_len) { 14 + size_t output_size = input_len; 15 + 16 + for (int i = 0; i < num_replacements; i++) { 17 + const char *placeholder = replacements[i].placeholder; 18 + const char *value = replacements[i].value; 19 + size_t placeholder_len = strlen(placeholder); 20 + size_t value_len = strlen(value); 21 + 22 + const char *pos = input; 23 + while ((pos = strstr(pos, placeholder)) != NULL) { 24 + output_size = output_size - placeholder_len + value_len; 25 + pos += placeholder_len; 26 + } 27 + } 28 + 29 + char *output = malloc(output_size + 1); 30 + if (!output) return NULL; 31 + 32 + const char *read_pos = input; 33 + char *write_pos = output; 34 + size_t remaining = input_len; 35 + 36 + while (remaining > 0) { 37 + const char *nearest_match = NULL; 38 + size_t nearest_match_len = 0; 39 + const char *nearest_match_value = NULL; 40 + 41 + for (int i = 0; i < num_replacements; i++) { 42 + const char *match = strstr(read_pos, replacements[i].placeholder); 43 + if (match && (!nearest_match || match < nearest_match)) { 44 + nearest_match = match; 45 + nearest_match_len = strlen(replacements[i].placeholder); 46 + nearest_match_value = replacements[i].value; 47 + } 48 + } 49 + 50 + if (nearest_match) { 51 + size_t before_len = nearest_match - read_pos; 52 + memcpy(write_pos, read_pos, before_len); 53 + write_pos += before_len; 54 + 55 + size_t value_len = strlen(nearest_match_value); 56 + memcpy(write_pos, nearest_match_value, value_len); 57 + write_pos += value_len; 58 + 59 + read_pos = nearest_match + nearest_match_len; 60 + remaining = input_len - (read_pos - input); 61 + } else { 62 + memcpy(write_pos, read_pos, remaining); 63 + write_pos += remaining; 64 + remaining = 0; 65 + } 66 + } 67 + 68 + *write_pos = '\0'; 69 + *output_len = write_pos - output; 70 + return output; 71 + } 72 + 73 + int main(int argc, char **argv) { 74 + if (argc < 3) { 75 + fprintf(stderr, "Usage: %s <input.js> <output.h> [KEY=value...]\n", argv[0]); 76 + fprintf(stderr, "Example: %s core.js snapshot.h VERSION=1.0.0 GIT_HASH=abc123\n", argv[0]); 77 + return 1; 78 + } 79 + 80 + const char *input_file = argv[1]; 81 + const char *output_file = argv[2]; 82 + 83 + int num_replacements = argc - 3; 84 + replacement_t *replacements = malloc(sizeof(replacement_t) * num_replacements); 85 + if (!replacements && num_replacements > 0) { 86 + fprintf(stderr, "Error: Failed to allocate memory for replacements\n"); 87 + return 1; 88 + } 89 + 90 + int replacement_idx = 0; 91 + for (int i = 3; i < argc; i++) { 92 + char *arg = strdup(argv[i]); 93 + char *equals = strchr(arg, '='); 94 + if (equals) { 95 + *equals = '\0'; 96 + 97 + replacements[replacement_idx].placeholder = malloc(strlen(arg) + 5); 98 + sprintf(replacements[replacement_idx].placeholder, "{{%s}}", arg); 99 + replacements[replacement_idx].value = strdup(equals + 1); 100 + 101 + printf("template replacement: %s -> %s\n", replacements[replacement_idx].placeholder, replacements[replacement_idx].value); 102 + replacement_idx++; 103 + } 104 + free(arg); 105 + } 106 + 107 + num_replacements = replacement_idx; 108 + 109 + FILE *in = fopen(input_file, "r"); 110 + if (!in) { 111 + fprintf(stderr, "Error: Cannot open input file: %s\n", input_file); 112 + return 1; 113 + } 114 + 115 + fseek(in, 0, SEEK_END); 116 + long file_size = ftell(in); 117 + fseek(in, 0, SEEK_SET); 118 + 119 + char *js_code_original = malloc(file_size + 1); 120 + if (!js_code_original) { 121 + fprintf(stderr, "Error: Memory allocation failed\n"); 122 + fclose(in); 123 + return 1; 124 + } 125 + 126 + fread(js_code_original, 1, file_size, in); 127 + js_code_original[file_size] = '\0'; 128 + fclose(in); 129 + 130 + size_t processed_len; 131 + char *js_code = replace_templates(js_code_original, file_size, replacements, num_replacements, &processed_len); 132 + 133 + if (!js_code) { 134 + fprintf(stderr, "Error: Template replacement failed\n"); 135 + free(js_code_original); 136 + return 1; 137 + } 138 + 139 + free(js_code_original); 140 + 141 + struct js *js = js_create_dynamic(1024 * 1024, 10 * 1024 * 1024); 142 + if (!js) { 143 + fprintf(stderr, "Error: Failed to create JS runtime\n"); 144 + free(js_code); 145 + return 1; 146 + } 147 + 148 + ant_runtime_init(js); 149 + 150 + jsval_t result = js_eval(js, js_code, processed_len); 151 + if (js_type(result) == JS_ERR) { 152 + fprintf(stderr, "Error: Failed to evaluate JS code:\n%s\n", js_str(js, result)); 153 + js_destroy(js); 154 + free(js_code); 155 + return 1; 156 + } 157 + 158 + size_t total_mem, min_free, cstack; 159 + js_stats(js, &total_mem, &min_free, &cstack); 160 + size_t used_mem = js_getbrk(js); 161 + 162 + FILE *out = fopen(output_file, "w"); 163 + if (!out) { 164 + fprintf(stderr, "Error: Cannot open output file: %s\n", output_file); 165 + js_destroy(js); 166 + free(js_code); 167 + return 1; 168 + } 169 + 170 + fprintf(out, "/* Auto-generated snapshot from %s */\n", input_file); 171 + fprintf(out, "/* DO NOT EDIT - Generated during build */\n\n"); 172 + fprintf(out, "#ifndef ANT_SNAPSHOT_DATA_H\n"); 173 + fprintf(out, "#define ANT_SNAPSHOT_DATA_H\n\n"); 174 + fprintf(out, "#include <stddef.h>\n\n"); 175 + 176 + fprintf(out, "static const char ant_snapshot_source[] = \n"); 177 + fprintf(out, "\""); 178 + 179 + for (size_t i = 0; i < processed_len; i++) { 180 + char c = js_code[i]; 181 + switch (c) { 182 + case '\n': fprintf(out, "\\n"); break; 183 + case '\r': fprintf(out, "\\r"); break; 184 + case '\t': fprintf(out, "\\t"); break; 185 + case '\\': fprintf(out, "\\\\"); break; 186 + case '"': fprintf(out, "\\\""); break; 187 + default: 188 + if (c >= 32 && c < 127) { 189 + fputc(c, out); 190 + } else { 191 + fprintf(out, "\\x%02x", (unsigned char)c); 192 + } 193 + break; 194 + } 195 + 196 + if (i > 0 && i % 80 == 0) fprintf(out, "\"\n\""); 197 + } 198 + 199 + fprintf(out, "\";\n\n"); 200 + fprintf(out, "static const size_t ant_snapshot_source_len = %zu;\n\n", processed_len); 201 + fprintf(out, "/* memory usage after evaluation: %zu bytes */\n", used_mem); 202 + fprintf(out, "/* total memory: %zu bytes */\n", total_mem); 203 + fprintf(out, "static const size_t ant_snapshot_mem_size = %zu;\n\n", used_mem); 204 + 205 + fprintf(out, "#endif /* ANT_SNAPSHOT_DATA_H */\n"); 206 + 207 + fclose(out); 208 + js_destroy(js); 209 + free(js_code); 210 + 211 + for (int i = 0; i < num_replacements; i++) { 212 + free(replacements[i].placeholder); 213 + free(replacements[i].value); 214 + } 215 + free(replacements); 216 + 217 + printf("snapshot generated successfully: %s\n", output_file); 218 + printf(" original size: %ld bytes\n", file_size); 219 + printf(" processed size: %zu bytes\n", processed_len); 220 + printf(" memory used: %zu bytes\n", used_mem); 221 + printf(" replacements: %d\n", num_replacements); 222 + 223 + return 0; 224 + }