@@ -208,11 +208,54 @@ static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint
208
208
return b != NULL && jl_atomic_load_relaxed (& b -> value ) != NULL ? fl_ctx -> T : fl_ctx -> F ;
209
209
}
210
210
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
+
211
215
static value_t fl_current_module_counter (fl_context_t * fl_ctx , value_t * args , uint32_t nargs ) JL_NOTSAFEPOINT
212
216
{
213
217
jl_ast_context_t * ctx = jl_ast_ctx (fl_ctx );
214
218
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 );
216
259
}
217
260
218
261
static int jl_is_number (jl_value_t * v )
@@ -240,13 +283,51 @@ static value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nar
240
283
return fl_ctx -> F ;
241
284
}
242
285
286
+ static value_t fl_julia_push_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
287
+ {
288
+ argcount (fl_ctx , "julia-push-closure-expr" , nargs , 1 );
289
+ // Check if the head of the symbol at `args[0]` is (method <name>) or (method (outerref <name>))
290
+ // and if so, push the name onto the `parsed_method_stack`
291
+ value_t arg = args [0 ];
292
+ if (iscons (arg )) {
293
+ value_t head = car_ (arg );
294
+ if (head == symbol (fl_ctx , "method" )) {
295
+ value_t name = car_ (cdr_ (arg ));
296
+ if (issymbol (name )) {
297
+ arraylist_push (& parsed_method_stack , (void * )name );
298
+ return fl_ctx -> T ;
299
+ }
300
+ if (iscons (name )) {
301
+ value_t head = car_ (name );
302
+ if (head == symbol (fl_ctx , "outerref" )) {
303
+ value_t name_inner = car_ (cdr_ (name ));
304
+ assert (issymbol (name_inner ));
305
+ arraylist_push (& parsed_method_stack , (void * )name_inner );
306
+ return fl_ctx -> T ;
307
+ }
308
+ }
309
+ }
310
+ }
311
+ return fl_ctx -> F ;
312
+ }
313
+
314
+ static value_t fl_julia_pop_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
315
+ {
316
+ argcount (fl_ctx , "julia-pop-closure-expr" , nargs , 0 );
317
+ // Pop the top of the `parsed_method_stack`
318
+ arraylist_pop (& parsed_method_stack );
319
+ return fl_ctx -> NIL ;
320
+ }
321
+
243
322
static jl_value_t * scm_to_julia_ (fl_context_t * fl_ctx , value_t e , jl_module_t * mod );
244
323
245
324
static const builtinspec_t julia_flisp_ast_ext [] = {
246
325
{ "defined-julia-global" , fl_defined_julia_global }, // TODO: can we kill this safepoint
247
326
{ "nothrow-julia-global" , fl_nothrow_julia_global },
248
327
{ "current-julia-module-counter" , fl_current_module_counter },
249
328
{ "julia-scalar?" , fl_julia_scalar },
329
+ { "julia-push-closure-expr" , fl_julia_push_closure_expr },
330
+ { "julia-pop-closure-expr" , fl_julia_pop_closure_expr },
250
331
{ NULL , NULL }
251
332
};
252
333
0 commit comments