@@ -289,13 +289,21 @@ def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_nam
289289
290290 f . puts '{'
291291 lineno += 1
292+ locals_referenced = 0
292293 # locals is nil outside methods
293294 locals &.reverse_each &.with_index { |param , i |
294295 next unless Symbol === param
295296 param = param . to_s
296297 lvar = local_candidates . include? ( param )
297298 next unless lvar or local_ptrs . include? ( param )
298299 f . puts "VALUE *const #{ param } __ptr = (VALUE *)&ec->cfp->ep[#{ -3 - i } ];"
300+ if i > 63
301+ # That's a lot of locals in a Primitive! Unlikely but possible.
302+ # In that case, set every bit.
303+ locals_referenced = ( ( 1 <<64 ) -1 )
304+ else
305+ locals_referenced |= ( 1 << i )
306+ end
299307 f . puts "MAYBE_UNUSED(const VALUE) #{ param } = *#{ param } __ptr;" if lvar
300308 lineno += lvar ? 2 : 1
301309 }
@@ -310,7 +318,7 @@ def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_nam
310318 f . puts
311319 lineno += 3
312320
313- return lineno , f . string
321+ return lineno , f . string , locals_referenced
314322end
315323
316324def mk_builtin_header file
@@ -351,12 +359,14 @@ def mk_builtin_header file
351359 f . puts
352360 lineno = __LINE__ - lineno - 1
353361 line_file = file
362+ reads_writes_locals = { }
354363
355364 inlines . each { |cfunc_name , ( body_lineno , text , locals , func_name ) |
356365 if String === cfunc_name
357366 f . puts "static VALUE #{ cfunc_name } (struct rb_execution_context_struct *ec, const VALUE self)"
358367 lineno += 1
359- lineno , str = generate_cexpr ( ofile , lineno , line_file , body_lineno , text , locals , func_name )
368+ lineno , str , locals_referenced = generate_cexpr ( ofile , lineno , line_file , body_lineno , text , locals , func_name )
369+ reads_writes_locals [ cfunc_name ] = locals_referenced
360370 f . write str
361371 else
362372 # cinit!
@@ -384,9 +394,10 @@ def mk_builtin_header file
384394 f . puts " // table definition"
385395 f . puts " static const struct rb_builtin_function #{ table } [] = {"
386396 bs . each . with_index { |( func , ( argc , cfunc_name ) ) , i |
387- f . puts " RB_BUILTIN_FUNCTION(#{ i } , #{ func } , #{ cfunc_name } , #{ argc } ),"
397+ locals_bitset = "0x" +reads_writes_locals . fetch ( cfunc_name , 0 ) . to_s ( 16 )
398+ f . puts " RB_BUILTIN_FUNCTION(#{ i } , #{ func } , #{ cfunc_name } , #{ argc } , #{ locals_bitset } ),"
388399 }
389- f . puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0),"
400+ f . puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0, 0 ),"
390401 f . puts " };"
391402
392403 f . puts
0 commit comments