コード例 #1
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::createExtendFunc()
{
	llvm::Type* argTypes[] = {m_array->getType(), Type::Size};
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.extend", getModule());
	func->setDoesNotThrow();
	func->setDoesNotCapture(1);

	auto arrayPtr = &func->getArgumentList().front();
	arrayPtr->setName("arrayPtr");
	auto newSize = arrayPtr->getNextNode();
	newSize->setName("newSize");

	InsertPointGuard guard{m_builder};
	m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func));
	auto dataPtr = m_builder.CreateBitCast(arrayPtr, Type::BytePtr->getPointerTo(), "dataPtr");// TODO: Use byte* in Array
	auto sizePtr = m_builder.CreateStructGEP(getType(), arrayPtr, 1, "sizePtr");
	auto capPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 2, "capPtr");
	auto data = m_builder.CreateLoad(dataPtr, "data");
	auto size = m_builder.CreateLoad(sizePtr, "size");
	auto extSize = m_builder.CreateNUWSub(newSize, size, "extSize");
	auto newData = m_reallocFunc.call(m_builder, {data, newSize}, "newData"); // TODO: Check realloc result for null
	auto extPtr = m_builder.CreateGEP(newData, size, "extPtr");
	m_builder.CreateMemSet(extPtr, m_builder.getInt8(0), extSize, 16);
	m_builder.CreateStore(newData, dataPtr);
	m_builder.CreateStore(newSize, sizePtr);
	m_builder.CreateStore(newSize, capPtr);
	m_builder.CreateRetVoid();
	return func;
}
コード例 #2
0
ファイル: BasicBlock.cpp プロジェクト: EarthDollar/farmer
llvm::Function* LocalStack::getStackPrepareFunc()
{
	static const auto c_funcName = "stack.prepare";
	if (auto func = getModule()->getFunction(c_funcName))
		return func;

	llvm::Type* argsTys[] = {Type::WordPtr, Type::Size->getPointerTo(), Type::Size, Type::Size, Type::Size, Type::BytePtr};
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::WordPtr, argsTys, false), llvm::Function::PrivateLinkage, c_funcName, getModule());
	func->setDoesNotThrow();
	func->setDoesNotAccessMemory(1);
	func->setDoesNotAlias(2);
	func->setDoesNotCapture(2);

	auto checkBB = llvm::BasicBlock::Create(func->getContext(), "Check", func);
	auto updateBB = llvm::BasicBlock::Create(func->getContext(), "Update", func);
	auto outOfStackBB = llvm::BasicBlock::Create(func->getContext(), "OutOfStack", func);

	auto iter = func->arg_begin();
	llvm::Argument* base = &(*iter++);
	base->setName("base");
	llvm::Argument* sizePtr = &(*iter++);
	sizePtr->setName("size.ptr");
	llvm::Argument* min = &(*iter++);
	min->setName("min");
	llvm::Argument* max = &(*iter++);
	max->setName("max");
	llvm::Argument* diff = &(*iter++);
	diff->setName("diff");
	llvm::Argument* jmpBuf = &(*iter);
	jmpBuf->setName("jmpBuf");

	InsertPointGuard guard{m_builder};
	m_builder.SetInsertPoint(checkBB);
	auto sizeAlignment = getModule()->getDataLayout().getABITypeAlignment(Type::Size);
	auto size = m_builder.CreateAlignedLoad(sizePtr, sizeAlignment, "size");
	auto minSize = m_builder.CreateAdd(size, min, "size.min", false, true);
	auto maxSize = m_builder.CreateAdd(size, max, "size.max", true, true);
	auto minOk = m_builder.CreateICmpSGE(minSize, m_builder.getInt64(0), "ok.min");
	auto maxOk = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(RuntimeManager::stackSizeLimit), "ok.max");
	auto ok = m_builder.CreateAnd(minOk, maxOk, "ok");
	m_builder.CreateCondBr(ok, updateBB, outOfStackBB, Type::expectTrue);

	m_builder.SetInsertPoint(updateBB);
	auto newSize = m_builder.CreateNSWAdd(size, diff, "size.next");
	m_builder.CreateAlignedStore(newSize, sizePtr, sizeAlignment);
	auto sp = m_builder.CreateGEP(base, size, "sp");
	m_builder.CreateRet(sp);

	m_builder.SetInsertPoint(outOfStackBB);
	auto longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::eh_sjlj_longjmp);
	m_builder.CreateCall(longjmp, {jmpBuf});
	m_builder.CreateUnreachable();

	return func;
}
コード例 #3
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::getReallocFunc()
{
	if (auto func = getModule()->getFunction("ext_realloc"))
		return func;

	llvm::Type* reallocArgTypes[] = {Type::BytePtr, Type::Size};
	auto reallocFunc = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, reallocArgTypes, false), llvm::Function::ExternalLinkage, "ext_realloc", getModule());
	reallocFunc->setDoesNotThrow();
	reallocFunc->setDoesNotAlias(0);
	reallocFunc->setDoesNotCapture(1);
	return reallocFunc;
}
コード例 #4
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::createFreeFunc()
{
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, m_array->getType(), false), llvm::Function::PrivateLinkage, "array.free", getModule());
	func->setDoesNotThrow();
	func->setDoesNotCapture(1);

	auto freeFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::BytePtr, false), llvm::Function::ExternalLinkage, "ext_free", getModule());
	freeFunc->setDoesNotThrow();
	freeFunc->setDoesNotCapture(1);

	auto arrayPtr = &func->getArgumentList().front();
	arrayPtr->setName("arrayPtr");

	InsertPointGuard guard{m_builder};
	m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func));
	auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr");
	auto data = m_builder.CreateLoad(dataPtr, "data");
	auto mem = m_builder.CreateBitCast(data, Type::BytePtr, "mem");
	m_builder.CreateCall(freeFunc, mem);
	m_builder.CreateRetVoid();
	return func;
}
コード例 #5
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::createArrayPushFunc()
{
	llvm::Type* argTypes[] = {m_array->getType(), Type::Word};
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.push", getModule());
	func->setDoesNotThrow();
	func->setDoesNotCapture(1);

	auto arrayPtr = &func->getArgumentList().front();
	arrayPtr->setName("arrayPtr");
	auto value = arrayPtr->getNextNode();
	value->setName("value");

	InsertPointGuard guard{m_builder};
	auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", func);
	auto reallocBB = llvm::BasicBlock::Create(m_builder.getContext(), "Realloc", func);
	auto pushBB = llvm::BasicBlock::Create(m_builder.getContext(), "Push", func);

	m_builder.SetInsertPoint(entryBB);
	auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr");
	auto sizePtr = m_builder.CreateStructGEP(getType(), arrayPtr, 1, "sizePtr");
	auto capPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 2, "capPtr");
	auto data = m_builder.CreateLoad(dataPtr, "data");
	auto size = m_builder.CreateLoad(sizePtr, "size");
	auto cap = m_builder.CreateLoad(capPtr, "cap");
	auto reallocReq = m_builder.CreateICmpEQ(cap, size, "reallocReq");
	m_builder.CreateCondBr(reallocReq, reallocBB, pushBB);

	m_builder.SetInsertPoint(reallocBB);
	auto newCap = m_builder.CreateNUWAdd(cap, m_builder.getInt64(c_reallocStep), "newCap");
	auto reallocSize = m_builder.CreateShl(newCap, 5, "reallocSize"); // size in bytes: newCap * 32
	auto bytes = m_builder.CreateBitCast(data, Type::BytePtr, "bytes");
	auto newBytes = m_reallocFunc.call(m_builder, {bytes, reallocSize}, "newBytes");
	auto newData = m_builder.CreateBitCast(newBytes, Type::WordPtr, "newData");
	m_builder.CreateStore(newData, dataPtr);
	m_builder.CreateStore(newCap, capPtr);
	m_builder.CreateBr(pushBB);

	m_builder.SetInsertPoint(pushBB);
	auto dataPhi = m_builder.CreatePHI(Type::WordPtr, 2, "dataPhi");
	dataPhi->addIncoming(data, entryBB);
	dataPhi->addIncoming(newData, reallocBB);
	auto newElemPtr = m_builder.CreateGEP(dataPhi, size, "newElemPtr");
	m_builder.CreateStore(value, newElemPtr);
	auto newSize = m_builder.CreateNUWAdd(size, m_builder.getInt64(1), "newSize");
	m_builder.CreateStore(newSize, sizePtr);
	m_builder.CreateRetVoid();

	return func;
}
コード例 #6
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::createGetPtrFunc()
{
	llvm::Type* argTypes[] = {m_array->getType(), Type::Size};
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::WordPtr, argTypes, false), llvm::Function::PrivateLinkage, "array.getPtr", getModule());
	func->setDoesNotThrow();
	func->setDoesNotCapture(1);

	auto arrayPtr = &func->getArgumentList().front();
	arrayPtr->setName("arrayPtr");
	auto index = arrayPtr->getNextNode();
	index->setName("index");

	InsertPointGuard guard{m_builder};
	m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func));
	auto dataPtr = m_builder.CreateBitCast(arrayPtr, Type::BytePtr->getPointerTo(), "dataPtr");
	auto data = m_builder.CreateLoad(dataPtr, "data");
	auto bytePtr = m_builder.CreateGEP(data, index, "bytePtr");
	auto wordPtr = m_builder.CreateBitCast(bytePtr, Type::WordPtr, "wordPtr");
	m_builder.CreateRet(wordPtr);
	return func;
}
コード例 #7
0
ファイル: Array.cpp プロジェクト: Matt90o/cpp-ethereum
llvm::Function* Array::createArraySetFunc()
{
	llvm::Type* argTypes[] = {m_array->getType(), Type::Size, Type::Word};
	auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.set", getModule());
	func->setDoesNotThrow();
	func->setDoesNotCapture(1);

	auto arrayPtr = &func->getArgumentList().front();
	arrayPtr->setName("arrayPtr");
	auto index = arrayPtr->getNextNode();
	index->setName("index");
	auto value = index->getNextNode();
	value->setName("value");

	InsertPointGuard guard{m_builder};
	m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func));
	auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr");
	auto data = m_builder.CreateLoad(dataPtr, "data");
	auto valuePtr = m_builder.CreateGEP(data, index, "valuePtr");
	m_builder.CreateStore(value, valuePtr);
	m_builder.CreateRetVoid();
	return func;
}