def provide_subprogram_access(inner_provider): # This provider is composed of several providers in the following # manner: # 1. A first transformer (get_subprogram_access_signature) # constructs dynamically the Signature object of the subprogram # being accessed and returns the pair (access_sig, subp_sig) # where access_sig is the signature of the function which # creates the subprogram access, and subp_sig is the signature # of the subprogram being accessed. # # 2. A second transformer (inner_provider) transforms the second # element of this pair in order to retrieve the forward and # backward implementations of the subprogram being accessed. # # 3. A third transformer (subprogram_access_provider) creates the # definition of the subprogram access is finally constructed # using the pair (access_sig, subp_defs). @Transformer.as_transformer def get_subprogram_access_signature(sig): if isinstance(sig.name, access_paths.Subprogram): if sig.output_domain == ptr_dom: if sig.name.interface.does_return: input_domains = sig.userdata[:-1] output_domain = sig.userdata[-1] else: input_domains = sig.userdata output_domain = None subp_signature = Signature( sig.name.subp_obj, tuple(input_domains), output_domain, tuple(sig.name.interface.out_indices)) return sig, subp_signature @def_provider def subprogram_access_provider(args): access_sig, subp_defs = args subp = access_sig.name.subp_obj interface = access_sig.name.interface return (access_paths_ops.subp_address(ptr_dom, subp, interface, subp_defs), access_paths_ops.inv_subp_address()) return (get_subprogram_access_signature >> (Transformer.identity() & inner_provider) >> subprogram_access_provider)
def subp_ret_typer(inner): """ :param types.Typer[lal.AdaNode] inner: Typer for return type components. :rtype: types.Typer[lal.AdaNode] """ @Transformer.as_transformer def get_components(hint): if hint.is_a(ExtendedCallReturnType): return (hint.out_indices, hint.out_types if hint.ret_type is None else hint.out_types + (hint.ret_type, )) @Transformer.as_transformer def to_output(x): out_indices, out_types = x return types.FunOutput(tuple(out_indices), out_types) return (get_components >> (Transformer.identity() & inner.lifted()) >> to_output)
def provider(): return ( original_signature >> (Transformer.identity() & actual_interp.def_provider_builder) >> transform_implementation) | model_provider