28 makeFromJsonFunction = NULL;
29 getJsonFunction = NULL;
30 getInterprocessJsonFunction = 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;
54 if (isType(typeName, module))
70bool VuoCompilerType::isType(
string typeName, Module *module)
72 return (module->getNamedValue(typeName +
"_makeFromJson") != NULL);
78void VuoCompilerType::parse(
void)
85 getInterprocessJsonFunction =
parser->
getFunction(typeName +
"_getInterprocessJson");
90 if (! makeFromJsonFunction)
91 VUserLog(
"Error: Couldn't find %s_makeFromJson() function.", typeName.c_str());
92 if (! getJsonFunction)
93 VUserLog(
"Error: Couldn't find %s_getJson() function.", typeName.c_str());
94 if (! getSummaryFunction)
95 VUserLog(
"Error: Couldn't find %s_getSummary() function.", typeName.c_str());
97 llvmArgumentType = getJsonFunction->getFunctionType()->getParamType(0);
98 if (getJsonFunction->getFunctionType()->getNumParams() == 2)
99 llvmSecondArgumentType = getJsonFunction->getFunctionType()->getParamType(1);
100 else if (getJsonFunction->getFunctionType()->getNumParams() != 1)
103 raw_string_ostream oss(s);
104 oss <<
"Expected a function with 1 or 2 parameters, got " << getJsonFunction->getFunctionType()->getNumParams() <<
" for function `";
105 getJsonFunction->getFunctionType()->print(oss);
111 llvmReturnType = makeFromJsonFunction->getReturnType();
112 if (llvmReturnType->isVoidTy())
114 isReturnPassedAsArgument =
true;
115 llvmReturnType = makeFromJsonFunction->arg_begin()->getType();
118 parseOrGenerateStringFromValueFunction(
false);
119 if (getInterprocessJsonFunction)
120 parseOrGenerateStringFromValueFunction(
true);
122 parseOrGenerateRetainOrReleaseFunction(
true);
123 parseOrGenerateRetainOrReleaseFunction(
false);
129set<string> VuoCompilerType::globalsToRename(
void)
153void VuoCompilerType::parseOrGenerateStringFromValueFunction(
bool isInterprocess)
155 string functionName = (
getBase()->
getModuleKey() + (isInterprocess ?
"_getInterprocessString" :
"_getString")).c_str();
158 Function *chosenJsonFromValueFunction = (isInterprocess ? getInterprocessJsonFunction : getJsonFunction);
162 PointerType *pointerToCharType = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
163 FunctionType *getJsonFunctionType = chosenJsonFromValueFunction->getFunctionType();
165 Type *returnType = pointerToCharType;
167 vector<Type *> functionParams;
168 for (
int i = 0; i < getJsonFunctionType->getNumParams(); ++i)
169 functionParams.push_back(getJsonFunctionType->getParamType(i));
171 FunctionType *functionType = FunctionType::get(returnType, functionParams,
false);
172 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName, module);
177 if (function->isDeclaration())
179 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function);
182 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args, ++argIndex)
185 ostringstream argName;
186 argName <<
"value" << argIndex;
187 value->setName(argName.str().c_str());
194 vector<Value *> getJsonArgs;
195 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args)
198 getJsonArgs.push_back(value);
200 CallInst *getJsonReturn = CallInst::Create(chosenJsonFromValueFunction, getJsonArgs,
"", block);
202 BitCastInst *getJsonReturnCasted =
new BitCastInst(getJsonReturn, jsonObjectToJsonStringExtFunction->getFunctionType()->getParamType(0),
"", block);
204 vector<Value *> jsonObjectToJsonStringExtArgs;
205 jsonObjectToJsonStringExtArgs.push_back(getJsonReturnCasted);
206 jsonObjectToJsonStringExtArgs.push_back(ConstantInt::get(module->getContext(), APInt(32, JSON_C_TO_STRING_PLAIN)));
207 CallInst *jsonObjectToJsonStringExtReturn = CallInst::Create(jsonObjectToJsonStringExtFunction, jsonObjectToJsonStringExtArgs,
"", block);
209 CallInst *strdupReturn = CallInst::Create(strdupFunction, jsonObjectToJsonStringExtReturn,
"", block);
211 CallInst::Create(jsonObjectPutFunction, getJsonReturnCasted,
"", block);
213 ReturnInst::Create(module->getContext(), strdupReturn, block);
217 getInterprocessStringFunction = function;
219 getStringFunction = function;
238void VuoCompilerType::parseOrGenerateRetainOrReleaseFunction(
bool isRetain)
245 vector<Type *> functionParams;
246 functionParams.push_back(llvmArgumentType);
247 if (llvmSecondArgumentType)
248 functionParams.push_back(llvmSecondArgumentType);
250 FunctionType *functionType = FunctionType::get(Type::getVoidTy(module->getContext()), functionParams,
false);
251 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName, module);
256 if (function->isDeclaration())
258 BasicBlock *block = BasicBlock::Create(module->getContext(),
"", function);
260 Function::arg_iterator args = function->arg_begin();
263 if (!llvmSecondArgumentType)
268 arg =
new LoadInst(arg,
"unloweredStruct",
false, block);
275 if (llvmArgumentType->isPointerTy())
281 if (llvmSecondArgumentType->isPointerTy())
284 Value *secondArg = args++;
289 ReturnInst::Create(module->getContext(), block);
293 retainFunction = function;
295 releaseFunction = function;
318 Value *jsonValue = CallInst::Create(jsonTokenerParseFunction, stringValue,
"valueAsJson", block);
320 vector<Value *> makeFromJsonArgs;
321 int jsonParamIndex = makeFromJsonFunctionInModule->getFunctionType()->getNumParams() - 1;
322 Type *jsonParamType =
static_cast<PointerType *
>(makeFromJsonFunctionInModule->getFunctionType()->getParamType(jsonParamIndex));
323 Value *jsonArg =
new BitCastInst(jsonValue, jsonParamType,
"", block);
324 makeFromJsonArgs.push_back(jsonArg);
326 Value *dataPointer =
nullptr;
330 dataPointer =
new BitCastInst(makeFromJsonReturn, llvmReturnType,
"valueFromString", block);
334 Value *makeFromJsonReturn = CallInst::Create(makeFromJsonFunctionInModule, makeFromJsonArgs,
"valueFromString", block);
341 CallInst::Create(jsonObjectPutFunction, jsonValue,
"", block);
356 return generateFunctionCallWithTypeParameter(module, block, arg, getStringFunction);
369 if (getInterprocessStringFunction)
370 return generateFunctionCallWithTypeParameter(module, block, arg, getInterprocessStringFunction);
385 return generateFunctionCallWithTypeParameter(module, block, arg, getSummaryFunction);
393 generateFunctionCallWithTypeParameter(module, block, arg, retainFunction);
401 generateFunctionCallWithTypeParameter(module, block, arg, releaseFunction);
410 bool isUnloweredStructPointerParameter)
412 vector<Value *> args;
413 if (!llvmSecondArgumentType)
415 Type *parameterType = functionType->getParamType(parameterIndex);
417 if (!isReturnPassedAsArgument)
419 bool isLoweredAsUsual =
true;
420 if (parameterType->isPointerTy() && !llvmArgumentType->isPointerTy())
421 isLoweredAsUsual =
false;
423 if (isLoweredAsUsual)
426 arg =
new BitCastInst(arg, PointerType::getUnqual(parameterType),
"dataPointerCasted", block);
427 arg =
new LoadInst(arg,
"data",
false, block);
432 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
438 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
445 if (! isUnloweredStructPointerParameter)
448 arg =
new BitCastInst(arg, PointerType::getUnqual(llvmReturnType),
"dataStructCasted", block);
449 for (
int i = 0; i < 2; ++i)
452 if (currArg->getType()->isPointerTy())
454 Type *parameterType = functionType->getParamType(parameterIndex + i);
455 currArg =
new BitCastInst(currArg, parameterType,
"dataCasted", block);
457 args.push_back(currArg);
463 Type *parameterType = functionType->getParamType(parameterIndex);
464 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
478 vector<Value *> args;
480 if (llvmSecondArgumentType)
483 if (!llvmSecondArgumentType)
485 if (!isReturnPassedAsArgument)
488 return new BitCastInst(argPointer, PointerType::getUnqual(llvmReturnType),
"dataPointerCasted", block);
495 size_t totalArgByteCount = 0;
496 for (
auto arg : args)
497 totalArgByteCount += module->getDataLayout().getTypeStoreSize(arg->getType());
499 Value *dataPointer =
new AllocaInst(llvmReturnType, 0,
"dataPointer", block);
500 Value *dataPointerAsBytePointer =
new BitCastInst(dataPointer, PointerType::getUnqual(IntegerType::get(module->getContext(), 8)),
"dataBytePointer", block);
502 size_t argByteOffset = 0;
503 for (
auto arg : args)
506 Value *offsetValue = ConstantInt::get(module->getContext(), APInt(64, argByteOffset));
507 Value *offsetDataPointer = GetElementPtrInst::Create(
nullptr, dataPointerAsBytePointer, offsetValue,
"", block);
508 size_t storeByteCount =
module->getDataLayout().getTypeStoreSize(arg->getType());
509 size_t allocByteCount =
module->getDataLayout().getTypeAllocSize(arg->getType());
511 argByteOffset += allocByteCount;
525Value * VuoCompilerType::generateFunctionCallWithTypeParameter(Module *module, BasicBlock *block, Value *arg, Function *sourceFunction)
528 vector<Value *> args =
convertPortDataToArgs(module, block, arg, function->getFunctionType(), 0,
false);
529 return CallInst::Create(function, args,
"", block);
537 Type *type = llvmReturnType;
538 if (isReturnPassedAsArgument)
539 type =
static_cast<PointerType *
>(llvmReturnType)->getElementType();
541 return module->getDataLayout().getTypeAllocSize(type);
549 Type *type = llvmReturnType;
550 if (isReturnPassedAsArgument)
551 type =
static_cast<PointerType *
>(llvmReturnType)->getElementType();
553 return module->getDataLayout().getTypeStoreSize(type);
561 Type *type = PointerType::getUnqual(llvmReturnType);
562 if (isReturnPassedAsArgument)
563 type = llvmReturnType;
565 return new BitCastInst(voidPointer, type,
"", block);
573 vector<Type *> types;
574 types.push_back(llvmArgumentType);
575 if (llvmSecondArgumentType)
576 types.push_back(llvmSecondArgumentType);
585 return PointerType::getUnqual(llvmReturnType);
595 return getJsonFunction->getAttributes();
630 return getInterprocessStringFunction != NULL;
638 return areEqualFunction != NULL && isLessThanFunction != NULL;