def handle_struct_passing(builder, alloca_func, largs, signature): """ Handle signatures with structs. If signature.struct_by_reference is set, we need to pass in structs by reference, and retrieve struct return values by refererence through an additional argument. Structs are always loaded as pointers. Complex numbers are always immediate struct values. """ for i, (arg_type, larg) in enumerate(zip(signature.args, largs)): if minitypes.pass_by_ref(arg_type): if signature.struct_by_reference: if arg_type.is_complex: new_arg = alloca_func(arg_type) builder.store(larg, new_arg) larg = new_arg largs[i] = larg if signature.struct_by_reference and minitypes.pass_by_ref(signature.return_type): return_value = alloca_func(signature.return_type) largs.append(return_value) return return_value return None
def handle_struct_passing(builder, alloca_func, largs, signature): """ Handle signatures with structs. If signature.struct_by_reference is set, we need to pass in structs by reference, and retrieve struct return values by refererence through an additional argument. Structs are always loaded as pointers. Complex numbers are always immediate struct values. """ for i, (arg_type, larg) in enumerate(zip(signature.args, largs)): if minitypes.pass_by_ref(arg_type): if signature.struct_by_reference: if arg_type.is_complex: new_arg = alloca_func(arg_type) builder.store(larg, new_arg) larg = new_arg largs[i] = larg if (signature.struct_by_reference and minitypes.pass_by_ref(signature.return_type)): return_value = alloca_func(signature.return_type) largs.append(return_value) return return_value return None
def visit_FuncCallNode(self, node): llvm_args = list(self.results(node.args)) llvm_func = self.visit(node.func_or_pointer) signature = node.func_or_pointer.type if signature.struct_by_reference: result = handle_struct_passing(self.builder, self.alloca, llvm_args, signature) llvm_call = self.builder.call(llvm_func, llvm_args) if node.inline: self.inline_calls.append(llvm_call) if signature.struct_by_reference and minitypes.pass_by_ref(signature.return_type): return self.builder.load(result) else: return llvm_call
def visit_FuncCallNode(self, node): llvm_args = list(self.results(node.args)) llvm_func = self.visit(node.func_or_pointer) signature = node.func_or_pointer.type if signature.struct_by_reference: result = handle_struct_passing( self.builder, self.alloca, llvm_args, signature) llvm_call = self.builder.call(llvm_func, llvm_args) if node.inline: self.inline_calls.append(llvm_call) if (signature.struct_by_reference and minitypes.pass_by_ref(signature.return_type)): return self.builder.load(result) else: return llvm_call