@@ -499,7 +499,7 @@ function make_oc_ref(
499
499
):: Core.OpaqueClosure
500
500
if Base. isassigned (oc_captures)
501
501
return oc_captures[]
502
- else
502
+ else
503
503
ores = ccall (
504
504
:jl_new_opaque_closure_from_code_info ,
505
505
Any,
@@ -553,6 +553,37 @@ function rewrite_insts!(ir, interp, guaranteed_error)
553
553
return ir, any_changed
554
554
end
555
555
556
+ function rewrite_argnumbers_by_one! (ir)
557
+ # Add one dummy argument at the beginning
558
+ pushfirst! (ir. argtypes, Nothing)
559
+
560
+ # Re-write all references to existing arguments to their new index (N + 1)
561
+ for idx = 1 : length (ir. stmts)
562
+ urs = Core. Compiler. userefs (ir. stmts[idx][:inst ])
563
+ changed = false
564
+ it = Core. Compiler. iterate (urs)
565
+ while it != = nothing
566
+ (ur, next) = it
567
+ old = Core. Compiler. getindex (ur)
568
+ if old isa Core. Argument
569
+ # Replace the Argument(n) with Argument(n + 1)
570
+ Core. Compiler. setindex! (ur, Core. Argument (old. n + 1 ))
571
+ changed = true
572
+ end
573
+ it = Core. Compiler. iterate (urs, next)
574
+ end
575
+ if changed
576
+ @static if VERSION < v " 1.11"
577
+ Core. Compiler. setindex! (ir. stmts[idx], Core. Compiler. getindex (urs), :inst )
578
+ else
579
+ Core. Compiler. setindex! (ir. stmts[idx], Core. Compiler. getindex (urs), :stmt )
580
+ end
581
+ end
582
+ end
583
+
584
+ return nothing
585
+ end
586
+
556
587
# Generator function which ensures that all calls to the function are executed within the ReactantInterpreter
557
588
# In particular this entails two pieces:
558
589
# 1) We enforce the use of the ReactantInterpreter method table when generating the original methodinstance
@@ -666,6 +697,9 @@ function call_with_reactant_generator(
666
697
) || guaranteed_error
667
698
ir, any_changed = rewrite_insts! (ir, interp, guaranteed_error)
668
699
end
700
+
701
+
702
+ rewrite_argnumbers_by_one! (ir)
669
703
670
704
src = ccall (:jl_new_code_info_uninit , Ref{CC. CodeInfo}, ())
671
705
src. slotnames = fill (:none , length (ir. argtypes) + 1 )
@@ -674,6 +708,7 @@ function call_with_reactant_generator(
674
708
src. rettype = rt
675
709
src = CC. ir_to_codeinf! (src, ir)
676
710
711
+
677
712
if DEBUG_INTERP[]
678
713
safe_print (" src" , src)
679
714
end
@@ -784,38 +819,34 @@ function call_with_reactant_generator(
784
819
785
820
ocva = false # method.isva
786
821
787
- ocnargs = method. nargs - 1
822
+ ocnargs = Int ( method. nargs)
788
823
# octup = Tuple{mi.specTypes.parameters[2:end]...}
789
824
# octup = Tuple{method.sig.parameters[2:end]...}
790
- octup = Tuple{tys[2 : end ]. .. }
825
+ octup = Tuple{tys[1 : end ]. .. }
791
826
ocva = false
792
827
793
828
# jl_new_opaque_closure forcibly executes in the current world... This means that we won't get the right
794
829
# inner code during compilation without special handling (i.e. call_in_world_total).
795
830
# Opaque closures also require taking the function argument. We can work around the latter
796
831
# if the function is stateless. But regardless, to work around this we sadly create/compile the opaque closure
797
832
798
- dict, make_oc = if Base. issingletontype (fn)
799
- Base. Ref {Core.OpaqueClosure} (), make_oc_ref
800
- else
801
- Dict {fn,Core.OpaqueClosure} (), make_oc_dict
802
- end
833
+ dict, make_oc = (Base. Ref {Core.OpaqueClosure} (), make_oc_ref)
803
834
804
835
push! (oc_capture_vec, dict)
805
836
806
837
oc = if false && Base. issingletontype (fn)
807
838
res = Core. _call_in_world_total (
808
839
world, make_oc, dict, octup, rt, src, ocnargs, ocva, fn. instance
809
840
):: Core.OpaqueClosure
810
-
811
841
else
812
842
farg = fn_args[1 ]
843
+ farg = nothing
813
844
rep = Expr (:call , make_oc, dict, octup, rt, src, ocnargs, ocva, farg)
814
845
push_inst! (rep)
815
846
Core. SSAValue (length (overdubbed_code))
816
847
end
817
848
818
- push_inst! (Expr (:call , oc, fn_args[2 : end ]. .. ))
849
+ push_inst! (Expr (:call , oc, fn_args[1 : end ]. .. ))
819
850
820
851
ocres = Core. SSAValue (length (overdubbed_code))
821
852
0 commit comments