void genprim_array_trace(compile_t* c, reach_type_t* t) { codegen_startfun(c, t->trace_fn, NULL, NULL); LLVMSetFunctionCallConv(t->trace_fn, LLVMCCallConv); LLVMValueRef ctx = LLVMGetParam(t->trace_fn, 0); LLVMValueRef arg = LLVMGetParam(t->trace_fn, 1); // Read the base pointer. LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, ""); LLVMValueRef pointer = field_value(c, object, 3); // Trace the base pointer. LLVMValueRef args[2]; args[0] = ctx; args[1] = pointer; gencall_runtime(c, "pony_trace", args, 2, ""); trace_array_elements(c, t, ctx, object, pointer); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); }
void genprim_array_serialise_trace(compile_t* c, reach_type_t* t) { // Generate the serialise_trace function. t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name), c->trace_type); codegen_startfun(c, t->serialise_trace_fn, NULL, NULL); LLVMSetFunctionCallConv(t->serialise_trace_fn, LLVMCCallConv); LLVMSetLinkage(t->serialise_trace_fn, LLVMExternalLinkage); LLVMValueRef ctx = LLVMGetParam(t->serialise_trace_fn, 0); LLVMValueRef arg = LLVMGetParam(t->serialise_trace_fn, 1); LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, ""); // Read the size. LLVMValueRef size = field_value(c, object, 1); // Calculate the size of the element type. ast_t* typeargs = ast_childidx(t->ast, 2); ast_t* typearg = ast_child(typeargs); reach_type_t* t_elem = reach_type(c->reach, typearg); size_t abisize = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type); LLVMValueRef l_size = LLVMConstInt(c->intptr, abisize, false); // Reserve space for the array elements. LLVMValueRef pointer = field_value(c, object, 3); LLVMValueRef args[3]; args[0] = ctx; args[1] = pointer; args[2] = LLVMBuildMul(c->builder, size, l_size, ""); gencall_runtime(c, "pony_serialise_reserve", args, 3, ""); // Trace the array elements. trace_array_elements(c, t, ctx, object, pointer); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); }