|
7 | 7 | #include <stdlib.h>
|
8 | 8 | #include <stdio.h>
|
9 | 9 | #include <string.h>
|
| 10 | + |
10 | 11 | #ifdef _OS_WINDOWS_
|
11 | 12 | #include <malloc.h>
|
12 | 13 | #endif
|
@@ -215,11 +216,46 @@ static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint
|
215 | 216 | decode_restriction_value(pku) : jl_atomic_load_relaxed(&b->value)) != NULL ? fl_ctx->T : fl_ctx->F;
|
216 | 217 | }
|
217 | 218 |
|
218 |
| -static value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT |
| 219 | +// Used to generate a unique suffix for a given symbol (e.g. variable or type name) |
| 220 | +// first argument contains a stack of method definitions seen so far by `closure-convert` in flisp. |
| 221 | +// if the top of the stack is non-NIL, we use it to augment the suffix so that it becomes |
| 222 | +// of the form $top_level_method_name##$counter, where `counter` is the smallest integer |
| 223 | +// such that the resulting name is not already defined in the current module's bindings. |
| 224 | +// If the top of the stack is NIL, we simply return the current module's counter. |
| 225 | +// This ensures that precompile statements are a bit more stable across different versions |
| 226 | +// of a codebase. see #53719 |
| 227 | +static value_t fl_module_unique_name(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) |
219 | 228 | {
|
| 229 | + argcount(fl_ctx, "julia-module-unique-name", nargs, 1); |
220 | 230 | jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
|
221 |
| - assert(ctx->module); |
222 |
| - return fixnum(jl_module_next_counter(ctx->module)); |
| 231 | + jl_module_t *m = ctx->module; |
| 232 | + assert(m != NULL); |
| 233 | + // Get the outermost function name from the `parsed_method_stack` top |
| 234 | + char *funcname = NULL; |
| 235 | + value_t parsed_method_stack = args[0]; |
| 236 | + if (parsed_method_stack != fl_ctx->NIL) { |
| 237 | + value_t bottom_stack_symbol = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "last")), parsed_method_stack); |
| 238 | + funcname = tosymbol(fl_ctx, bottom_stack_symbol, "julia-module-unique-name")->name; |
| 239 | + } |
| 240 | + size_t sz = funcname != NULL ? strlen(funcname) + 32 : 32; // 32 is enough for the suffix |
| 241 | + char *buf = (char*)alloca(sz); |
| 242 | + if (funcname != NULL && strchr(funcname, '#') == NULL) { |
| 243 | + for (int i = 0; ; i++) { |
| 244 | + snprintf(buf, sz, "%s##%d", funcname, i); |
| 245 | + jl_sym_t *sym = jl_symbol(buf); |
| 246 | + JL_LOCK(&m->lock); |
| 247 | + if (jl_get_module_binding(m, sym, 0) == NULL) { // make sure this name is not already taken |
| 248 | + jl_get_module_binding(m, sym, 1); // create the binding |
| 249 | + JL_UNLOCK(&m->lock); |
| 250 | + return symbol(fl_ctx, buf); |
| 251 | + } |
| 252 | + JL_UNLOCK(&m->lock); |
| 253 | + } |
| 254 | + } |
| 255 | + else { |
| 256 | + snprintf(buf, sz, "%d", jl_module_next_counter(m)); |
| 257 | + } |
| 258 | + return symbol(fl_ctx, buf); |
223 | 259 | }
|
224 | 260 |
|
225 | 261 | static int jl_is_number(jl_value_t *v)
|
@@ -252,7 +288,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m
|
252 | 288 | static const builtinspec_t julia_flisp_ast_ext[] = {
|
253 | 289 | { "defined-julia-global", fl_defined_julia_global }, // TODO: can we kill this safepoint
|
254 | 290 | { "nothrow-julia-global", fl_nothrow_julia_global },
|
255 |
| - { "current-julia-module-counter", fl_current_module_counter }, |
| 291 | + { "current-julia-module-counter", fl_module_unique_name }, |
256 | 292 | { "julia-scalar?", fl_julia_scalar },
|
257 | 293 | { NULL, NULL }
|
258 | 294 | };
|
|
0 commit comments