27 makeFromJsonFunction = NULL;
28 getJsonFunction = NULL;
29 getInterprocessJsonFunction = NULL;
30 makeFromStringFunction = NULL;
31 getStringFunction = NULL;
32 getInterprocessStringFunction = NULL;
33 getSummaryFunction = NULL;
34 areEqualFunction = NULL;
35 isLessThanFunction = NULL;
36 retainFunction = NULL;
37 releaseFunction = NULL;
38 llvmArgumentType =
nullptr;
39 llvmSecondArgumentType =
nullptr;
40 llvmReturnType =
nullptr;
41 isReturnPassedAsArgument =
false;
52 if (! isType(typeName,
module))
62 bool VuoCompilerType::isType(
string typeName, Module *module)
64 return (
module->getNamedValue(typeName +
"_makeFromJson") != NULL);
70 void VuoCompilerType::parse(
void)
77 getInterprocessJsonFunction =
parser->
getFunction(typeName +
"_getInterprocessJson");
82 if (! makeFromJsonFunction)
83 VUserLog(
"Error: Couldn't find %s_makeFromJson() function.", typeName.c_str());
84 if (! getJsonFunction)
85 VUserLog(
"Error: Couldn't find %s_getJson() function.", typeName.c_str());
86 if (! getSummaryFunction)
87 VUserLog(
"Error: Couldn't find %s_getSummary() function.", typeName.c_str());
89 llvmArgumentType = getJsonFunction->getFunctionType()->getParamType(0);
90 if (getJsonFunction->getFunctionType()->getNumParams() == 2)
91 llvmSecondArgumentType = getJsonFunction->getFunctionType()->getParamType(1);
92 else if (getJsonFunction->getFunctionType()->getNumParams() != 1)
95 raw_string_ostream oss(s);
96 oss <<
"Expected a function with 1 or 2 parameters, got " << getJsonFunction->getFunctionType()->getNumParams() <<
" for function `";
97 getJsonFunction->getFunctionType()->print(oss);
103 llvmReturnType = makeFromJsonFunction->getReturnType();
104 if (llvmReturnType->isVoidTy())
106 isReturnPassedAsArgument =
true;
107 llvmReturnType = makeFromJsonFunction->arg_begin()->getType();
110 parseOrGenerateValueFromStringFunction();
111 parseOrGenerateStringFromValueFunction(
false);
112 if (getInterprocessJsonFunction)
113 parseOrGenerateStringFromValueFunction(
true);
115 parseOrGenerateRetainOrReleaseFunction(
true);
116 parseOrGenerateRetainOrReleaseFunction(
false);
122 set<string> VuoCompilerType::globalsToRename(
void)
145 void VuoCompilerType::parseOrGenerateValueFromStringFunction(
void)
154 PointerType *pointerToCharType = PointerType::get(IntegerType::get(
module->getContext(), 8), 0);
155 FunctionType *makeFromJsonFunctionType = makeFromJsonFunction->getFunctionType();
157 Type *returnType = makeFromJsonFunctionType->getReturnType();
159 vector<Type *> functionParams;
161 functionParams.push_back(makeFromJsonFunctionType->getParamType(0));
162 functionParams.push_back(pointerToCharType);
164 FunctionType *functionType = FunctionType::get(returnType, functionParams,
false);
165 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName,
module);
171 if (function->isDeclaration())
173 BasicBlock *block = BasicBlock::Create(
module->getContext(),
"",
function);
175 Function::arg_iterator args =
function->arg_begin();
176 Value *result = NULL;
180 result->setName(
"result");
188 CallInst *jsonTokenerParseReturn = CallInst::Create(jsonTokenerParseFunction, str,
"", block);
190 vector<Value *> makeFromJsonArgs;
192 makeFromJsonArgs.push_back(result);
193 makeFromJsonArgs.push_back(jsonTokenerParseReturn);
194 Value *makeFromJsonReturn = CallInst::Create(makeFromJsonFunction, makeFromJsonArgs,
"", block);
196 CallInst::Create(jsonObjectPutFunction, jsonTokenerParseReturn,
"", block);
198 Value *returnValue = (isReturnInParam ? NULL : makeFromJsonReturn);
199 ReturnInst::Create(
module->getContext(), returnValue, block);
202 makeFromStringFunction =
function;
223 void VuoCompilerType::parseOrGenerateStringFromValueFunction(
bool isInterprocess)
225 string functionName = (
getBase()->
getModuleKey() + (isInterprocess ?
"_getInterprocessString" :
"_getString")).c_str();
228 Function *chosenJsonFromValueFunction = (isInterprocess ? getInterprocessJsonFunction : getJsonFunction);
232 PointerType *pointerToCharType = PointerType::get(IntegerType::get(
module->getContext(), 8), 0);
233 FunctionType *getJsonFunctionType = chosenJsonFromValueFunction->getFunctionType();
235 Type *returnType = pointerToCharType;
237 vector<Type *> functionParams;
238 for (
int i = 0; i < getJsonFunctionType->getNumParams(); ++i)
239 functionParams.push_back(getJsonFunctionType->getParamType(i));
241 FunctionType *functionType = FunctionType::get(returnType, functionParams,
false);
242 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName,
module);
247 if (function->isDeclaration())
249 BasicBlock *block = BasicBlock::Create(
module->getContext(),
"",
function);
252 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args, ++argIndex)
255 ostringstream argName;
256 argName <<
"value" << argIndex;
257 value->setName(argName.str().c_str());
264 vector<Value *> getJsonArgs;
265 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args)
268 getJsonArgs.push_back(value);
270 CallInst *getJsonReturn = CallInst::Create(chosenJsonFromValueFunction, getJsonArgs,
"", block);
272 vector<Value *> jsonObjectToJsonStringExtArgs;
273 jsonObjectToJsonStringExtArgs.push_back(getJsonReturn);
274 jsonObjectToJsonStringExtArgs.push_back(ConstantInt::get(
module->getContext(), APInt(32, JSON_C_TO_STRING_PLAIN)));
275 CallInst *jsonObjectToJsonStringExtReturn = CallInst::Create(jsonObjectToJsonStringExtFunction, jsonObjectToJsonStringExtArgs,
"", block);
277 CallInst *strdupReturn = CallInst::Create(strdupFunction, jsonObjectToJsonStringExtReturn,
"", block);
279 CallInst::Create(jsonObjectPutFunction, getJsonReturn,
"", block);
281 ReturnInst::Create(
module->getContext(), strdupReturn, block);
285 getInterprocessStringFunction =
function;
287 getStringFunction =
function;
306 void VuoCompilerType::parseOrGenerateRetainOrReleaseFunction(
bool isRetain)
308 string functionName = (
getBase()->
getModuleKey() + (isRetain ?
"_retain" :
"_release")).c_str();
313 vector<Type *> functionParams;
314 functionParams.push_back(llvmArgumentType);
315 if (llvmSecondArgumentType)
316 functionParams.push_back(llvmSecondArgumentType);
318 FunctionType *functionType = FunctionType::get(Type::getVoidTy(
module->getContext()), functionParams,
false);
319 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName,
module);
324 if (function->isDeclaration())
326 BasicBlock *block = BasicBlock::Create(
module->getContext(),
"",
function);
328 Function::arg_iterator args =
function->arg_begin();
331 if (!llvmSecondArgumentType)
336 arg =
new LoadInst(arg,
"unloweredStruct",
false, block);
343 if (llvmArgumentType->isPointerTy())
349 if (llvmSecondArgumentType->isPointerTy())
352 Value *secondArg = args++;
357 ReturnInst::Create(
module->getContext(), block);
361 retainFunction =
function;
363 releaseFunction =
function;
378 if (isReturnPassedAsArgument)
380 vector<Value *> functionArgs;
381 functionArgs.push_back(arg);
383 return new BitCastInst(returnVariable, llvmReturnType,
"valueFromString", block);
387 Value *returnValue = CallInst::Create(
function, arg,
"valueFromString", block);
402 return generateFunctionCallWithTypeParameter(
module, block, arg, getStringFunction);
415 if (getInterprocessStringFunction)
416 return generateFunctionCallWithTypeParameter(
module, block, arg, getInterprocessStringFunction);
431 return generateFunctionCallWithTypeParameter(
module, block, arg, getSummaryFunction);
440 generateFunctionCallWithTypeParameter(
module, block, arg, retainFunction);
449 generateFunctionCallWithTypeParameter(
module, block, arg, releaseFunction);
458 bool isUnloweredStructPointerParameter)
460 vector<Value *> args;
461 if (!llvmSecondArgumentType)
463 Type *parameterType = functionType->getParamType(parameterIndex);
465 if (!isReturnPassedAsArgument)
467 bool isLoweredAsUsual =
true;
468 if (parameterType->isPointerTy() && !llvmArgumentType->isPointerTy())
469 isLoweredAsUsual =
false;
471 if (isLoweredAsUsual)
474 arg =
new BitCastInst(arg, PointerType::getUnqual(parameterType),
"dataPointerCasted", block);
475 arg =
new LoadInst(arg,
"data",
false, block);
480 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
486 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
493 if (! isUnloweredStructPointerParameter)
496 arg =
new BitCastInst(arg, PointerType::getUnqual(llvmReturnType),
"dataStructCasted", block);
497 for (
int i = 0; i < 2; ++i)
500 if (currArg->getType()->isPointerTy())
502 Type *parameterType = functionType->getParamType(parameterIndex + i);
503 currArg =
new BitCastInst(currArg, parameterType,
"dataCasted", block);
505 args.push_back(currArg);
511 Type *parameterType = functionType->getParamType(parameterIndex);
512 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
526 vector<Value *> args;
528 if (llvmSecondArgumentType)
531 if (!llvmSecondArgumentType)
533 if (!isReturnPassedAsArgument)
536 return new BitCastInst(argPointer, PointerType::getUnqual(llvmReturnType),
"dataPointerCasted", block);
543 size_t totalArgByteCount = 0;
544 for (
auto arg : args)
545 totalArgByteCount +=
module->getDataLayout().getTypeStoreSize(arg->getType());
549 Value *dataPointer =
new AllocaInst(llvmReturnType, 0,
"dataPointer", block);
550 Value *dataPointerAsBytePointer =
new BitCastInst(dataPointer, PointerType::getUnqual(IntegerType::get(
module->getContext(), 8)),
"dataBytePointer", block);
552 size_t argByteOffset = 0;
553 for (
auto arg : args)
556 Value *offsetValue = ConstantInt::get(
module->getContext(), APInt(64, argByteOffset));
557 Value *offsetDataPointer = GetElementPtrInst::Create(
nullptr, dataPointerAsBytePointer, offsetValue,
"", block);
558 size_t argByteCount =
module->getDataLayout().getTypeStoreSize(arg->getType());
559 size_t copyByteCount = max(argByteCount, argByteCount - (dataByteCount - (argByteOffset + argByteCount)));
561 argByteOffset += argByteCount;
575 Value * VuoCompilerType::generateFunctionCallWithTypeParameter(Module *module, BasicBlock *block, Value *arg, Function *sourceFunction)
579 return CallInst::Create(
function, args,
"", block);
587 Type *type = llvmReturnType;
588 if (isReturnPassedAsArgument)
589 type =
static_cast<PointerType *
>(llvmReturnType)->getElementType();
591 size_t size =
module->getDataLayout().getTypeStoreSize(type);
600 Type *type = PointerType::getUnqual(llvmReturnType);
601 if (isReturnPassedAsArgument)
602 type = llvmReturnType;
604 return new BitCastInst(voidPointer, type,
"", block);
613 return llvmReturnType->isPointerTy() || llvmReturnType->isStructTy();
621 vector<Type *> types;
622 types.push_back(llvmArgumentType);
623 if (llvmSecondArgumentType)
624 types.push_back(llvmSecondArgumentType);
633 return PointerType::getUnqual(llvmReturnType);
643 return getJsonFunction->getAttributes();
678 return getInterprocessStringFunction != NULL;
686 return areEqualFunction != NULL && isLessThanFunction != NULL;