From 7c47c436555528cea0a789bbc21400e4a731a1f1 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 2 Jun 2025 08:48:49 -0500 Subject: [PATCH] improve globfs performance --- scripts/build.ce | 12 +++--- source/qjs_io.c | 101 ++++++++++++++++++++++++++++++----------------- source/qjs_js.c | 5 ++- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/scripts/build.ce b/scripts/build.ce index 6ecdf8b1..d5d6276a 100644 --- a/scripts/build.ce +++ b/scripts/build.ce @@ -2,20 +2,20 @@ var io = use('io') var js = use('js') +var time = use('time') var build_root = '.cell/build' log.console("Building scripts...") +var now = time.number() + // Find and compile all .cm and .ce files from root -var files = io.enumerate('', true) // recursive from root +var files = io.globfs(['**/*.cm', '**/*.ce', '!**/*.git', '!**/*.cell', '!**/subprojects'], '') + var compiled_count = 0 var error_count = 0 -files = files.filter(f => { - return (f.endsWith('.ce' || f.endsWith('.cm')) && !f.startsWith('.cell')) -}) - for (var file of files) { var src = io.slurp(file) var fullpath = io.realdir(file) + "/" + file @@ -39,7 +39,7 @@ for (var file of files) { } } -log.console("Build complete: " + compiled_count + " files compiled") +log.console("Build complete: " + compiled_count + " files compiled in " + (time.number()-now) + " seconds") if (error_count > 0) { log.console(" " + error_count + " errors") } diff --git a/source/qjs_io.c b/source/qjs_io.c index 3d3f3d89..b3104609 100644 --- a/source/qjs_io.c +++ b/source/qjs_io.c @@ -50,43 +50,6 @@ struct globdata { int recurse; }; -// Callback for globfs -static int globfs_cb(struct globdata *data, char *dir, char *file) -{ - int needfree = 0; - char *path; - if (dir[0] == 0) path = file; - else { - path = malloc(strlen(dir) + strlen(file) + 2); - path[0] = 0; - strcat(path,dir); - strcat(path,"/"); - strcat(path,file); - needfree = 1; - } - - char **glob = data->globs; - - while (*glob != NULL) { - if (wildmatch(*glob, path, WM_WILDSTAR) == WM_MATCH) - goto END; - glob++; - } - - PHYSFS_Stat stat; - PHYSFS_stat(path, &stat); - if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) { - PHYSFS_enumerate(path, globfs_cb, data); - goto END; - } - - JS_SetPropertyUint32(data->js, data->arr, data->idx++, JS_NewString(data->js,path)); - - END: - if (needfree) free(path); - return 1; -} - // Callback for enumerate static int enumerate_cb(void *udata, const char *dir, const char *fname) { @@ -229,6 +192,70 @@ JSC_SSCALL(io_match, ret = JS_NewBool(js,0); ) +// Callback for globfs, with support for negative patterns (e.g. "!**/.git") +static int globfs_cb(struct globdata *data, char *dir, char *file) +{ + int needfree = 0; + char *path; + PHYSFS_Stat stat; + char **glob; + + if (dir[0] == 0) + path = file; + else { + path = malloc(strlen(dir) + strlen(file) + 2); + path[0] = 0; + strcat(path, dir); + strcat(path, "/"); + strcat(path, file); + needfree = 1; + } + + // Grab filetype now + PHYSFS_stat(path, &stat); + + if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) { + // Check negative patterns first: if directory matches a "!…" pattern, skip it + for (glob = data->globs; *glob != NULL; glob++) { + if ((*glob)[0] == '!') { + const char *neg_pattern = (*glob) + 1; + if (wildmatch(neg_pattern, path, WM_WILDSTAR) == WM_MATCH) + goto END; + } + } + // Not excluded: recurse into this directory + PHYSFS_enumerate(path, globfs_cb, data); + goto END; + } + + // It's a file—first see if it matches any negative pattern + for (glob = data->globs; *glob != NULL; glob++) { + if ((*glob)[0] == '!') { + const char *neg_pattern = (*glob) + 1; + if (wildmatch(neg_pattern, path, WM_WILDSTAR) == WM_MATCH) + goto END; + } + } + + // Now check positive patterns ("**/*.cm", "**/*.ce", etc.) + for (glob = data->globs; *glob != NULL; glob++) { + if ((*glob)[0] == '!') + continue; + if (wildmatch(*glob, path, WM_WILDSTAR) == WM_MATCH) { + JS_SetPropertyUint32(data->js, + data->arr, + data->idx++, + JS_NewString(data->js, path)); + break; + } + } + + END: + if (needfree) + free(path); + return 1; +} + JSC_CCALL(io_globfs, ret = JS_NewArray(js); struct globdata data; diff --git a/source/qjs_js.c b/source/qjs_js.c index 581ef0e6..b33e9692 100644 --- a/source/qjs_js.c +++ b/source/qjs_js.c @@ -59,8 +59,11 @@ JSC_CCALL(js_compile_blob, // JS_SetStripInfo(rt, JS_STRIP_DEBUG); size_t size; uint8_t *data = JS_WriteObject(js, &size, argv[0], JS_WRITE_OBJ_BYTECODE); + if (!data) { + return JS_ThrowInternalError(js, "Failed to serialize bytecode"); + } ret = js_new_blob_stoned_copy(js, data, size); - free(data); + js_free(js, data); ) JSC_CCALL(js_compile_unblob,