@@ -37,13 +37,20 @@ function callable_ret_type(sig, types)
3737end
3838
3939function build_callable (sig:: Type{<:Tuple} )
40- ir = Base. code_ircode_by_type (sig)[1 ][1 ]
41- bb, refs, types = derive_copyable_task_ir (BBCode (ir))
42- unoptimised_ir = IRCode (bb)
43- optimised_ir = Mooncake. optimise_ir! (unoptimised_ir)
44- mc_ret_type = callable_ret_type (sig, types)
45- mc = Mooncake. misty_closure (mc_ret_type, optimised_ir, refs... ; do_compile= true )
46- return mc, refs[end ]
40+ key = CacheKey (Base. get_world_counter (), sig)
41+ if haskey (mc_cache, key)
42+ v = fresh_copy (mc_cache[key])
43+ return v
44+ else
45+ ir = Base. code_ircode_by_type (sig)[1 ][1 ]
46+ bb, refs, types = derive_copyable_task_ir (BBCode (ir))
47+ unoptimised_ir = IRCode (bb)
48+ optimised_ir = Mooncake. optimise_ir! (unoptimised_ir)
49+ mc_ret_type = callable_ret_type (sig, types)
50+ mc = Mooncake. misty_closure (mc_ret_type, optimised_ir, refs... ; do_compile= true )
51+ mc_cache[key] = mc
52+ return mc, refs[end ]
53+ end
4754end
4855
4956mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<: MistyClosure }
@@ -53,6 +60,13 @@ mutable struct TapedTask{Tdynamic_scope,Tfargs,Tmc<:MistyClosure}
5360 const position:: Base.RefValue{Int32}
5461end
5562
63+ struct CacheKey
64+ world_age:: UInt
65+ key:: Any
66+ end
67+
68+ const mc_cache = Dict {CacheKey,MistyClosure} ()
69+
5670"""
5771 TapedTask(dynamic_scope::Any, f, args...; kwargs...)
5872
@@ -170,12 +184,27 @@ julia> consume(t)
170184[`Libtask.get_dynamic_scope`](@ref) to anything you like.
171185"""
172186function TapedTask (dynamic_scope:: Any , fargs... ; kwargs... )
173- seed_id! ()
174187 all_args = isempty (kwargs) ? fargs : (Core. kwcall, getfield (kwargs, :data ), fargs... )
188+ seed_id! ()
175189 mc, count_ref = build_callable (typeof (all_args))
176190 return TapedTask (dynamic_scope, all_args, mc, count_ref)
177191end
178192
193+ function fresh_copy (mc:: T ) where {T<: MistyClosure }
194+ new_captures = Mooncake. tuple_map (mc. oc. captures) do r
195+ if eltype (r) <: DynamicCallable
196+ return Base. RefValue (DynamicCallable ())
197+ elseif eltype (r) <: LazyCallable
198+ return _typeof (r)(eltype (r)())
199+ else
200+ return _typeof (r)()
201+ end
202+ end
203+ new_position = new_captures[end ]
204+ new_position[] = - 1
205+ return Mooncake. replace_captures (mc, new_captures), new_position
206+ end
207+
179208"""
180209 set_dynamic_scope!(t::TapedTask, new_dynamic_scope)::Nothing
181210
@@ -335,7 +364,7 @@ const TypeInfo = Tuple{Vector{Any},Dict{ID,Type}}
335364Central definition of typeof, which is specific to the use-required in this package.
336365"""
337366_typeof (x) = Base. _stable_typeof (x)
338- _typeof (x:: Tuple ) = Tuple{tuple_map (_typeof, x)... }
367+ _typeof (x:: Tuple ) = Tuple{map (_typeof, x)... }
339368_typeof (x:: NamedTuple{names} ) where {names} = NamedTuple{names,_typeof (Tuple (x))}
340369
341370"""
@@ -641,6 +670,8 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
641670 push! (inst_pairs, (id, inst))
642671 elseif Meta. isexpr (stmt, :gc_preserve_end )
643672 push! (inst_pairs, (id, inst))
673+ elseif Meta. isexpr (stmt, :throw_undef_if_not )
674+ push! (inst_pairs, (id, inst))
644675 elseif stmt isa Nothing
645676 push! (inst_pairs, (id, inst))
646677 elseif stmt isa GlobalRef
0 commit comments