Skip to content

Commit f8951b3

Browse files
committed
canonicalize names of nested functions and nested lambdas
1 parent 09400e4 commit f8951b3

File tree

6 files changed

+113
-7
lines changed

6 files changed

+113
-7
lines changed

src/ast.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,54 @@ static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint
208208
return b != NULL && jl_atomic_load_relaxed(&b->value) != NULL ? fl_ctx->T : fl_ctx->F;
209209
}
210210

211+
arraylist_t parsed_method_stack; // for keeping track of which methods are being parsed
212+
uv_mutex_t counter_table_lock;
213+
htable_t counter_table; // map from module_name -> inner htable; inner htable maps from char * -> uint32_t
214+
211215
static value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
212216
{
213217
jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
214218
assert(ctx->module);
215-
return fixnum(jl_module_next_counter(ctx->module));
219+
// Create a string of the form <$outermost_func_name>$counter
220+
// where counter is the next counter for the module obtained by calling `jl_module_next_counter`
221+
// Get the module name
222+
char *modname = jl_symbol_name(ctx->module->name);
223+
// Get the outermost function name from the `parsed_method_stack` top
224+
char *funcname = NULL;
225+
value_t funcname_v = parsed_method_stack.len > 0 ? (value_t)parsed_method_stack.items[0] : fl_ctx->NIL;
226+
if (funcname_v != fl_ctx->NIL) {
227+
funcname = symbol_name(fl_ctx, funcname_v);
228+
}
229+
// Create the string
230+
char buf[(funcname != NULL ? strlen(funcname) : 0) + 20];
231+
if (funcname != NULL && funcname[0] != '#') {
232+
uint32_t nxt;
233+
uv_mutex_lock(&counter_table_lock);
234+
// try to find the module name in the counter table, if it's not create a symbol table for it
235+
if (ptrhash_get(&counter_table, modname) == HT_NOTFOUND) {
236+
// if not found, add it to the counter table
237+
htable_t *new_table = (htable_t*)malloc_s(sizeof(htable_t));
238+
htable_new(new_table, 0);
239+
ptrhash_put(&counter_table, modname, new_table);
240+
}
241+
htable_t *mod_table = (htable_t*)ptrhash_get(&counter_table, modname);
242+
// try to find the function name in the module's counter table, if it's not found, add it
243+
if (ptrhash_get(mod_table, funcname) == HT_NOTFOUND) {
244+
// Don't forget to shift the counter by 2 and or it with 3
245+
// to avoid the counter being 0 or 1, which are reserved
246+
ptrhash_put(mod_table, funcname, (void*)(uintptr_t)3);
247+
}
248+
nxt = ((uint32_t)(uintptr_t)ptrhash_get(mod_table, funcname) >> 2);
249+
// Increment the counter and don't forget to shift it by 2 and or it with 3
250+
// to avoid the counter being 0 or 1, which are reserved
251+
ptrhash_put(mod_table, funcname, (void*)(uintptr_t)((nxt + 1) << 2 | 3));
252+
uv_mutex_unlock(&counter_table_lock);
253+
snprintf(buf, sizeof(buf), "%s%d", funcname, nxt);
254+
}
255+
else {
256+
snprintf(buf, sizeof(buf), "%d", jl_module_next_counter(ctx->module));
257+
}
258+
return symbol(fl_ctx, buf);
216259
}
217260

218261
static value_t fl_julia_current_file(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) JL_NOTSAFEPOINT
@@ -250,6 +293,42 @@ static value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nar
250293
return fl_ctx->F;
251294
}
252295

296+
static value_t fl_julia_push_closure_expr(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
297+
{
298+
argcount(fl_ctx, "julia-push-closure-expr", nargs, 1);
299+
// Check if the head of the symbol at `args[0]` is (method <name>) or (method (outerref <name>))
300+
// and if so, push the name onto the `parsed_method_stack`
301+
value_t arg = args[0];
302+
if (iscons(arg)) {
303+
value_t head = car_(arg);
304+
if (head == symbol(fl_ctx, "method")) {
305+
value_t name = car_(cdr_(arg));
306+
if (issymbol(name)) {
307+
arraylist_push(&parsed_method_stack, (void*)name);
308+
return fl_ctx->T;
309+
}
310+
if (iscons(name)) {
311+
value_t head = car_(name);
312+
if (head == symbol(fl_ctx, "outerref")) {
313+
value_t name_inner = car_(cdr_(name));
314+
assert(issymbol(name_inner));
315+
arraylist_push(&parsed_method_stack, (void*)name_inner);
316+
return fl_ctx->T;
317+
}
318+
}
319+
}
320+
}
321+
return fl_ctx->F;
322+
}
323+
324+
static value_t fl_julia_pop_closure_expr(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
325+
{
326+
argcount(fl_ctx, "julia-pop-closure-expr", nargs, 0);
327+
// Pop the top of the `parsed_method_stack`
328+
arraylist_pop(&parsed_method_stack);
329+
return fl_ctx->NIL;
330+
}
331+
253332
static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
254333

255334
static const builtinspec_t julia_flisp_ast_ext[] = {
@@ -259,6 +338,8 @@ static const builtinspec_t julia_flisp_ast_ext[] = {
259338
{ "julia-scalar?", fl_julia_scalar },
260339
{ "julia-current-file", fl_julia_current_file },
261340
{ "julia-current-line", fl_julia_current_line },
341+
{ "julia-push-closure-expr", fl_julia_push_closure_expr },
342+
{ "julia-pop-closure-expr", fl_julia_pop_closure_expr },
262343
{ NULL, NULL }
263344
};
264345

src/datatype.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT
3636
len = strlen(n) - 1;
3737
else
3838
len = (end-n) - 1; // extract `f` from `#f#...`
39-
if (is10digit(n[1]))
39+
if (is10digit(n[1]) || is_anonfn_typename(n))
4040
return _jl_symbol(n, len+1);
4141
return _jl_symbol(&n[1], len);
4242
}

src/flisp/flisp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ value_t fl_cons(fl_context_t *fl_ctx, value_t a, value_t b) JL_NOTSAFEPOINT;
158158
value_t fl_list2(fl_context_t *fl_ctx, value_t a, value_t b) JL_NOTSAFEPOINT;
159159
value_t fl_listn(fl_context_t *fl_ctx, size_t n, ...) JL_NOTSAFEPOINT;
160160
value_t symbol(fl_context_t *fl_ctx, const char *str) JL_NOTSAFEPOINT;
161-
char *symbol_name(fl_context_t *fl_ctx, value_t v);
161+
char *symbol_name(fl_context_t *fl_ctx, value_t v) JL_NOTSAFEPOINT;
162162
int fl_is_keyword_name(const char *str, size_t len);
163163
value_t alloc_vector(fl_context_t *fl_ctx, size_t n, int init);
164164
size_t llength(value_t v);

src/init.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,10 @@ static void init_global_mutexes(void) {
742742
JL_MUTEX_INIT(&profile_show_peek_cond_lock, "profile_show_peek_cond_lock");
743743
}
744744

745+
extern arraylist_t parsed_method_stack;
746+
extern uv_mutex_t counter_table_lock;
747+
extern htable_t counter_table;
748+
745749
JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
746750
{
747751
// initialize many things, in no particular order
@@ -824,6 +828,9 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
824828

825829
jl_gc_init();
826830

831+
uv_mutex_init(&counter_table_lock);
832+
htable_new(&counter_table, 0);
833+
arraylist_new(&parsed_method_stack, 0);
827834
arraylist_new(&jl_linkage_blobs, 0);
828835
arraylist_new(&jl_image_relocs, 0);
829836
arraylist_new(&eytzinger_image_tree, 0);

src/julia-syntax.scm

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,7 +2370,7 @@
23702370
(= ,lhs ,(car rr))))
23712371
`(= ,lhs ,rhs)))
23722372

2373-
(define (expand-forms e)
2373+
(define (expand-forms- e)
23742374
(if (or (atom? e) (memq (car e) '(quote inert top core globalref outerref module toplevel ssavalue null true false meta using import export public thismodule toplevel-only)))
23752375
e
23762376
(let ((ex (get expand-table (car e) #f)))
@@ -2379,6 +2379,14 @@
23792379
(cons (car e)
23802380
(map expand-forms (cdr e)))))))
23812381

2382+
;; wrapper for `cl-convert-`
2383+
(define (expand-forms e)
2384+
(let ((pushed (julia-push-closure-expr e)))
2385+
(let ((res (expand-forms- e)))
2386+
(if pushed
2387+
(julia-pop-closure-expr))
2388+
res)))
2389+
23822390
;; table mapping expression head to a function expanding that form
23832391
(define expand-table
23842392
(table
@@ -3890,7 +3898,7 @@ f(x) = yt(x)
38903898
(list-tail (car (lam:vinfo lam)) (length (lam:args lam))))
38913899
(lambda-optimize-vars! lam))
38923900

3893-
(define (cl-convert e fname lam namemap defined toplevel interp opaq (globals (table)) (locals (table)))
3901+
(define (cl-convert- e fname lam namemap defined toplevel interp opaq (globals (table)) (locals (table)))
38943902
(if (and (not lam)
38953903
(not (and (pair? e) (memq (car e) '(lambda method macro opaque_closure)))))
38963904
(if (atom? e) e
@@ -4245,6 +4253,14 @@ f(x) = yt(x)
42454253
(cons (car e)
42464254
(map-cl-convert (cdr e) fname lam namemap defined toplevel interp opaq globals locals))))))))
42474255

4256+
;; wrapper for `cl-convert-`
4257+
(define (cl-convert e fname lam namemap defined toplevel interp opaq (globals (table)) (locals (table)))
4258+
(let ((pushed (julia-push-closure-expr e)))
4259+
(let ((res (cl-convert- e fname lam namemap defined toplevel interp opaq globals locals)))
4260+
(if pushed
4261+
(julia-pop-closure-expr))
4262+
res)))
4263+
42484264
(define (closure-convert e) (cl-convert e #f #f (table) (table) #f #f #f))
42494265

42504266
;; pass 5: convert to linear IR

src/julia_internal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "support/strtod.h"
1414
#include "gc-alloc-profiler.h"
1515
#include "support/rle.h"
16+
#include <ctype.h>
1617
#include <stdint.h>
1718
#include <uv.h>
1819
#include <llvm-c/Types.h>
@@ -842,12 +843,13 @@ jl_method_t *jl_make_opaque_closure_method(jl_module_t *module, jl_value_t *name
842843
int nargs, jl_value_t *functionloc, jl_code_info_t *ci, int isva, int isinferred);
843844
JL_DLLEXPORT int jl_is_valid_oc_argtype(jl_tupletype_t *argt, jl_method_t *source);
844845

845-
STATIC_INLINE int is_anonfn_typename(char *name)
846+
STATIC_INLINE int is_anonfn_typename(char *name) JL_NOTSAFEPOINT
846847
{
847848
if (name[0] != '#' || name[1] == '#')
848849
return 0;
849850
char *other = strrchr(name, '#');
850-
return other > &name[1] && other[1] > '0' && other[1] <= '9';
851+
// Check if the last character is a digit
852+
return other > &name[1] && isdigit(name[strlen(name) - 1]);
851853
}
852854

853855
// Each tuple can exist in one of 4 Vararg states:

0 commit comments

Comments
 (0)