|
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
|
@@ -160,11 +161,46 @@ static value_t fl_defined_julia_global(fl_context_t *fl_ctx, value_t *args, uint
|
160 | 161 | return (b != NULL && jl_atomic_load_relaxed(&b->owner) == b) ? fl_ctx->T : fl_ctx->F;
|
161 | 162 | }
|
162 | 163 |
|
163 |
| -static value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT |
| 164 | +// Used to generate a unique suffix for a given symbol (e.g. variable or type name) |
| 165 | +// first argument contains a stack of method definitions seen so far by `closure-convert` in flisp. |
| 166 | +// if the top of the stack is non-NIL, we use it to augment the suffix so that it becomes |
| 167 | +// of the form $top_level_method_name##$counter, where `counter` is the smallest integer |
| 168 | +// such that the resulting name is not already defined in the current module's bindings. |
| 169 | +// If the top of the stack is NIL, we simply return the current module's counter. |
| 170 | +// This ensures that precompile statements are a bit more stable across different versions |
| 171 | +// of a codebase. see #53719 |
| 172 | +static value_t fl_module_unique_name(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) |
164 | 173 | {
|
| 174 | + argcount(fl_ctx, "julia-module-unique-name", nargs, 1); |
165 | 175 | jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
|
166 |
| - assert(ctx->module); |
167 |
| - return fixnum(jl_module_next_counter(ctx->module)); |
| 176 | + jl_module_t *m = ctx->module; |
| 177 | + assert(m != NULL); |
| 178 | + // Get the outermost function name from the `parsed_method_stack` top |
| 179 | + char *funcname = NULL; |
| 180 | + value_t parsed_method_stack = args[0]; |
| 181 | + if (parsed_method_stack != fl_ctx->NIL) { |
| 182 | + value_t bottom_stack_symbol = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "last")), parsed_method_stack); |
| 183 | + funcname = tosymbol(fl_ctx, bottom_stack_symbol, "julia-module-unique-name")->name; |
| 184 | + } |
| 185 | + size_t sz = funcname != NULL ? strlen(funcname) + 32 : 32; // 32 is enough for the suffix |
| 186 | + char *buf = (char*)alloca(sz); |
| 187 | + if (funcname != NULL && strchr(funcname, '#') == NULL) { |
| 188 | + for (int i = 0; ; i++) { |
| 189 | + snprintf(buf, sz, "%s##%d", funcname, i); |
| 190 | + jl_sym_t *sym = jl_symbol(buf); |
| 191 | + JL_LOCK(&m->lock); |
| 192 | + if (jl_get_module_binding(m, sym, 0) == NULL) { // make sure this name is not already taken |
| 193 | + jl_get_module_binding(m, sym, 1); // create the binding |
| 194 | + JL_UNLOCK(&m->lock); |
| 195 | + return symbol(fl_ctx, buf); |
| 196 | + } |
| 197 | + JL_UNLOCK(&m->lock); |
| 198 | + } |
| 199 | + } |
| 200 | + else { |
| 201 | + snprintf(buf, sz, "%d", jl_module_next_counter(m)); |
| 202 | + } |
| 203 | + return symbol(fl_ctx, buf); |
168 | 204 | }
|
169 | 205 |
|
170 | 206 | static value_t fl_julia_current_file(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
|
@@ -206,7 +242,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m
|
206 | 242 |
|
207 | 243 | static const builtinspec_t julia_flisp_ast_ext[] = {
|
208 | 244 | { "defined-julia-global", fl_defined_julia_global }, // TODO: can we kill this safepoint
|
209 |
| - { "current-julia-module-counter", fl_current_module_counter }, |
| 245 | + { "current-julia-module-counter", fl_module_unique_name }, |
210 | 246 | { "julia-scalar?", fl_julia_scalar },
|
211 | 247 | { "julia-current-file", fl_julia_current_file },
|
212 | 248 | { "julia-current-line", fl_julia_current_line },
|
|
0 commit comments