27 makeFromJsonFunction = NULL;
28 getJsonFunction = NULL;
29 getInterprocessJsonFunction = NULL;
30 getStringFunction = NULL;
31 getInterprocessStringFunction = NULL;
32 getSummaryFunction = NULL;
33 areEqualFunction = NULL;
34 isLessThanFunction = NULL;
35 retainFunction = NULL;
36 releaseFunction = NULL;
37 llvmArgumentType =
nullptr;
38 llvmSecondArgumentType =
nullptr;
39 llvmReturnType =
nullptr;
40 isReturnPassedAsArgument =
false;
51 if (! isType(typeName,
module))
61bool VuoCompilerType::isType(
string typeName, Module *module)
63 return (
module->getNamedValue(typeName +
"_makeFromJson") != NULL);
69void VuoCompilerType::parse(
void)
76 getInterprocessJsonFunction =
parser->
getFunction(typeName +
"_getInterprocessJson");
81 if (! makeFromJsonFunction)
82 VUserLog(
"Error: Couldn't find %s_makeFromJson() function.", typeName.c_str());
83 if (! getJsonFunction)
84 VUserLog(
"Error: Couldn't find %s_getJson() function.", typeName.c_str());
85 if (! getSummaryFunction)
86 VUserLog(
"Error: Couldn't find %s_getSummary() function.", typeName.c_str());
88 llvmArgumentType = getJsonFunction->getFunctionType()->getParamType(0);
89 if (getJsonFunction->getFunctionType()->getNumParams() == 2)
90 llvmSecondArgumentType = getJsonFunction->getFunctionType()->getParamType(1);
91 else if (getJsonFunction->getFunctionType()->getNumParams() != 1)
94 raw_string_ostream oss(s);
95 oss <<
"Expected a function with 1 or 2 parameters, got " << getJsonFunction->getFunctionType()->getNumParams() <<
" for function `";
96 getJsonFunction->getFunctionType()->print(oss);
102 llvmReturnType = makeFromJsonFunction->getReturnType();
103 if (llvmReturnType->isVoidTy())
105 isReturnPassedAsArgument =
true;
106 llvmReturnType = makeFromJsonFunction->arg_begin()->getType();
109 parseOrGenerateStringFromValueFunction(
false);
110 if (getInterprocessJsonFunction)
111 parseOrGenerateStringFromValueFunction(
true);
113 parseOrGenerateRetainOrReleaseFunction(
true);
114 parseOrGenerateRetainOrReleaseFunction(
false);
120set<string> VuoCompilerType::globalsToRename(
void)
144void VuoCompilerType::parseOrGenerateStringFromValueFunction(
bool isInterprocess)
146 string functionName = (
getBase()->
getModuleKey() + (isInterprocess ?
"_getInterprocessString" :
"_getString")).c_str();
149 Function *chosenJsonFromValueFunction = (isInterprocess ? getInterprocessJsonFunction : getJsonFunction);
153 PointerType *pointerToCharType = PointerType::get(IntegerType::get(
module->getContext(), 8), 0);
154 FunctionType *getJsonFunctionType = chosenJsonFromValueFunction->getFunctionType();
156 Type *returnType = pointerToCharType;
158 vector<Type *> functionParams;
159 for (
int i = 0; i < getJsonFunctionType->getNumParams(); ++i)
160 functionParams.push_back(getJsonFunctionType->getParamType(i));
162 FunctionType *functionType = FunctionType::get(returnType, functionParams,
false);
163 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName,
module);
168 if (function->isDeclaration())
170 BasicBlock *block = BasicBlock::Create(
module->getContext(),
"", function);
173 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args, ++argIndex)
176 ostringstream argName;
177 argName <<
"value" << argIndex;
178 value->setName(argName.str().c_str());
185 vector<Value *> getJsonArgs;
186 for (Function::arg_iterator args = function->arg_begin(); args != function->arg_end(); ++args)
189 getJsonArgs.push_back(value);
191 CallInst *getJsonReturn = CallInst::Create(chosenJsonFromValueFunction, getJsonArgs,
"", block);
193 vector<Value *> jsonObjectToJsonStringExtArgs;
194 jsonObjectToJsonStringExtArgs.push_back(getJsonReturn);
195 jsonObjectToJsonStringExtArgs.push_back(ConstantInt::get(
module->getContext(), APInt(32, JSON_C_TO_STRING_PLAIN)));
196 CallInst *jsonObjectToJsonStringExtReturn = CallInst::Create(jsonObjectToJsonStringExtFunction, jsonObjectToJsonStringExtArgs,
"", block);
198 CallInst *strdupReturn = CallInst::Create(strdupFunction, jsonObjectToJsonStringExtReturn,
"", block);
200 CallInst::Create(jsonObjectPutFunction, getJsonReturn,
"", block);
202 ReturnInst::Create(
module->getContext(), strdupReturn, block);
206 getInterprocessStringFunction = function;
208 getStringFunction = function;
227void VuoCompilerType::parseOrGenerateRetainOrReleaseFunction(
bool isRetain)
234 vector<Type *> functionParams;
235 functionParams.push_back(llvmArgumentType);
236 if (llvmSecondArgumentType)
237 functionParams.push_back(llvmSecondArgumentType);
239 FunctionType *functionType = FunctionType::get(Type::getVoidTy(
module->getContext()), functionParams,
false);
240 function = Function::Create(functionType, GlobalValue::ExternalLinkage, functionName,
module);
245 if (function->isDeclaration())
247 BasicBlock *block = BasicBlock::Create(
module->getContext(),
"", function);
249 Function::arg_iterator args = function->arg_begin();
252 if (!llvmSecondArgumentType)
257 arg =
new LoadInst(arg,
"unloweredStruct",
false, block);
264 if (llvmArgumentType->isPointerTy())
270 if (llvmSecondArgumentType->isPointerTy())
273 Value *secondArg = args++;
278 ReturnInst::Create(
module->getContext(), block);
282 retainFunction = function;
284 releaseFunction = function;
307 Value *jsonValue = CallInst::Create(jsonTokenerParseFunction, stringValue,
"valueAsJson", block);
309 vector<Value *> makeFromJsonArgs;
310 int jsonParamIndex = makeFromJsonFunctionInModule->getFunctionType()->getNumParams() - 1;
311 Type *jsonParamType =
static_cast<PointerType *
>(makeFromJsonFunctionInModule->getFunctionType()->getParamType(jsonParamIndex));
312 Value *jsonArg =
new BitCastInst(jsonValue, jsonParamType,
"", block);
313 makeFromJsonArgs.push_back(jsonArg);
315 Value *dataPointer =
nullptr;
319 dataPointer =
new BitCastInst(makeFromJsonReturn, llvmReturnType,
"valueFromString", block);
323 Value *makeFromJsonReturn = CallInst::Create(makeFromJsonFunctionInModule, makeFromJsonArgs,
"valueFromString", block);
330 CallInst::Create(jsonObjectPutFunction, jsonValue,
"", block);
345 return generateFunctionCallWithTypeParameter(
module, block, arg, getStringFunction);
358 if (getInterprocessStringFunction)
359 return generateFunctionCallWithTypeParameter(
module, block, arg, getInterprocessStringFunction);
374 return generateFunctionCallWithTypeParameter(
module, block, arg, getSummaryFunction);
382 generateFunctionCallWithTypeParameter(
module, block, arg, retainFunction);
390 generateFunctionCallWithTypeParameter(
module, block, arg, releaseFunction);
399 bool isUnloweredStructPointerParameter)
401 vector<Value *> args;
402 if (!llvmSecondArgumentType)
404 Type *parameterType = functionType->getParamType(parameterIndex);
406 if (!isReturnPassedAsArgument)
408 bool isLoweredAsUsual =
true;
409 if (parameterType->isPointerTy() && !llvmArgumentType->isPointerTy())
410 isLoweredAsUsual =
false;
412 if (isLoweredAsUsual)
415 arg =
new BitCastInst(arg, PointerType::getUnqual(parameterType),
"dataPointerCasted", block);
416 arg =
new LoadInst(arg,
"data",
false, block);
421 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
427 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
434 if (! isUnloweredStructPointerParameter)
437 arg =
new BitCastInst(arg, PointerType::getUnqual(llvmReturnType),
"dataStructCasted", block);
438 for (
int i = 0; i < 2; ++i)
441 if (currArg->getType()->isPointerTy())
443 Type *parameterType = functionType->getParamType(parameterIndex + i);
444 currArg =
new BitCastInst(currArg, parameterType,
"dataCasted", block);
446 args.push_back(currArg);
452 Type *parameterType = functionType->getParamType(parameterIndex);
453 arg =
new BitCastInst(arg, parameterType,
"dataCasted", block);
467 vector<Value *> args;
469 if (llvmSecondArgumentType)
472 if (!llvmSecondArgumentType)
474 if (!isReturnPassedAsArgument)
477 return new BitCastInst(argPointer, PointerType::getUnqual(llvmReturnType),
"dataPointerCasted", block);
484 size_t totalArgByteCount = 0;
485 for (
auto arg : args)
486 totalArgByteCount +=
module->getDataLayout().getTypeStoreSize(arg->getType());
488 Value *dataPointer =
new AllocaInst(llvmReturnType, 0,
"dataPointer", block);
489 Value *dataPointerAsBytePointer =
new BitCastInst(dataPointer, PointerType::getUnqual(IntegerType::get(
module->getContext(), 8)),
"dataBytePointer", block);
491 size_t argByteOffset = 0;
492 for (
auto arg : args)
495 Value *offsetValue = ConstantInt::get(
module->getContext(), APInt(64, argByteOffset));
496 Value *offsetDataPointer = GetElementPtrInst::Create(
nullptr, dataPointerAsBytePointer, offsetValue,
"", block);
497 size_t storeByteCount =
module->getDataLayout().getTypeStoreSize(arg->getType());
498 size_t allocByteCount =
module->getDataLayout().getTypeAllocSize(arg->getType());
500 argByteOffset += allocByteCount;
514Value * VuoCompilerType::generateFunctionCallWithTypeParameter(Module *module, BasicBlock *block, Value *arg, Function *sourceFunction)
518 return CallInst::Create(function, args,
"", block);
526 Type *type = llvmReturnType;
527 if (isReturnPassedAsArgument)
528 type =
static_cast<PointerType *
>(llvmReturnType)->getElementType();
530 return module->getDataLayout().getTypeAllocSize(type);
538 Type *type = llvmReturnType;
539 if (isReturnPassedAsArgument)
540 type =
static_cast<PointerType *
>(llvmReturnType)->getElementType();
542 return module->getDataLayout().getTypeStoreSize(type);
550 Type *type = PointerType::getUnqual(llvmReturnType);
551 if (isReturnPassedAsArgument)
552 type = llvmReturnType;
554 return new BitCastInst(voidPointer, type,
"", block);
562 vector<Type *> types;
563 types.push_back(llvmArgumentType);
564 if (llvmSecondArgumentType)
565 types.push_back(llvmSecondArgumentType);
574 return PointerType::getUnqual(llvmReturnType);
584 return getJsonFunction->getAttributes();
619 return getInterprocessStringFunction != NULL;
627 return areEqualFunction != NULL && isLessThanFunction != NULL;