Ejemplo n.º 1
0
llvm::Value *
Target::SizeOf(LLVM_TYPE_CONST llvm::Type *type, 
               llvm::BasicBlock *insertAtEnd) {
    if (isa == Target::GENERIC &&
        lGenericTypeLayoutIndeterminate(type)) {
        llvm::Value *index[1] = { LLVMInt32(1) };
        LLVM_TYPE_CONST llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
        llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn)
        llvm::ArrayRef<llvm::Value *> arrayRef(&index[0], &index[1]);
        llvm::Instruction *gep = 
            llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "sizeof_gep",
                                            insertAtEnd);
#else
        llvm::Instruction *gep =
            llvm::GetElementPtrInst::Create(voidPtr, &index[0], &index[1],
                                            "sizeof_gep", insertAtEnd);
#endif
        if (is32Bit || g->opt.force32BitAddressing)
            return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, 
                                          "sizeof_int", insertAtEnd);
        else
            return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, 
                                          "sizeof_int", insertAtEnd);
    }

    const llvm::TargetData *td = GetTargetMachine()->getTargetData();
    Assert(td != NULL);
    uint64_t byteSize = td->getTypeSizeInBits(type) / 8;
    if (is32Bit || g->opt.force32BitAddressing)
        return LLVMInt32((int32_t)byteSize);
    else
        return LLVMInt64(byteSize);
}
Ejemplo n.º 2
0
		bool TypeInfo::objectHasCustomMove(const AST::TypeInstance& typeInstance) const {
			if (typeInstance.isClassDecl()) {
				// Assume a custom move function exists.
				return true;
			}
			
			if (typeInstance.isPrimitive()) {
				const auto& primitive = module_.getPrimitive(typeInstance);
				return primitive.hasCustomMove(*this,
				                               arrayRef(typeInstance.selfTemplateArgs()));
			}
			
			if (typeInstance.isVariant()) {
				for (const auto variantType: typeInstance.variantTypes()) {
					if (hasCustomMove(variantType)) {
						return true;
					}
				}
				
				return false;
			} else {
				if (typeInstance.isClassDef() &&
				     objectHasCustomMoveMethod(typeInstance)) {
					return true;
				}
				
				for (const auto var: typeInstance.variables()) {
					if (hasCustomMove(var->type())) {
						return true;
					}
				}
				
				return false;
			}
		}
Ejemplo n.º 3
0
 bool Write(uint8_t const * data, uint32_t count)
 {
   JNIEnv * env = jni::GetEnv();
   jni::TScopedLocalByteArrayRef arrayRef(env, env->NewByteArray(count));
   //this call copies native buffer to java byte array
   env->SetByteArrayRegion(arrayRef.get(), 0, count, reinterpret_cast<const jbyte *>(data));
   static jmethodID const writeMethod = jni::GetMethodID(env, m_self, "write", "([BI)Z");
   jboolean result = env->CallBooleanMethod(m_self, writeMethod, arrayRef.get(), static_cast<jint>(count));
   if (jni::HandleJavaException(env))
     return false;
   return result;
 }
Ejemplo n.º 4
0
		llvm::Value* genPrimitiveSizeOf(Function& function, const AST::Type* const type) {
			auto& module = function.module();
			
			IREmitter irEmitter(function);
			
			const auto& primitive = module.getPrimitive(*(type->getObjectType()));
			return primitive.emitMethod(irEmitter,
			                            METHOD_SIZEOF,
			                            arrayRef(type->templateArguments()),
			                            /*functionTemplateArguments=*/llvm::ArrayRef<AST::Value>(),
			                            /*args=*/{}, /*resultPtr=*/nullptr);
		}
Ejemplo n.º 5
0
		bool TypeInfo::hasCustomDestructor(const AST::Type* const type) const {
			if (type->isObject()) {
				if (type->isPrimitive()) {
					const auto& primitive = module_.getPrimitive(*(type->getObjectType()));
					return primitive.hasCustomDestructor(*this,
					                                     arrayRef(type->templateArguments()));
				} else {
					return objectHasCustomDestructor(*(type->getObjectType()));
				}
			} else {
				return type->isTemplateVar();
			}
		}
Ejemplo n.º 6
0
		bool TypeInfo::hasCustomMove(const AST::Type* const type) const {
			if (type->isObject()) {
				if (type->isPrimitive()) {
					const auto& primitive = module_.getPrimitive(*(type->getObjectType()));
					return primitive.hasCustomMove(*this,
					                               arrayRef(type->templateArguments()));
				} else {
					return objectHasCustomMove(*(type->getObjectType()))
					       // We have a custom move operation if there's a liveness indicator,
					       // since we need to set the source value to be dead.
					       || objectHasLivenessIndicator(*(type->getObjectType()));
				}
			} else {
				return type->isTemplateVar();
			}
		}
Ejemplo n.º 7
0
		bool TypeInfo::isSizeAlwaysKnown(const AST::Type* const type) const {
			switch (type->kind()) {
				case AST::Type::OBJECT:
					if (type->isPrimitive()) {
						const auto& primitive = module_.getPrimitive(*(type->getObjectType()));
						return primitive.isSizeAlwaysKnown(*this,
						                                   arrayRef(type->templateArguments()));
					} else {
						return isObjectSizeAlwaysKnown(*(type->getObjectType()));
					}
				case AST::Type::TEMPLATEVAR:
					return false;
				case AST::Type::ALIAS:
					return isSizeAlwaysKnown(type->resolveAliases());
				default:
					llvm_unreachable("Unknown AST type kind enum.");
			}
		}
Ejemplo n.º 8
0
llvm::Value *
Target::StructOffset(LLVM_TYPE_CONST llvm::Type *type, int element,
                     llvm::BasicBlock *insertAtEnd) {
    if (isa == Target::GENERIC && 
        lGenericTypeLayoutIndeterminate(type) == true) {
        llvm::Value *indices[2] = { LLVMInt32(0), LLVMInt32(element) };
        LLVM_TYPE_CONST llvm::PointerType *ptrType = llvm::PointerType::get(type, 0);
        llvm::Value *voidPtr = llvm::ConstantPointerNull::get(ptrType);
#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn)
        llvm::ArrayRef<llvm::Value *> arrayRef(&indices[0], &indices[2]);
        llvm::Instruction *gep = 
            llvm::GetElementPtrInst::Create(voidPtr, arrayRef, "offset_gep",
                                            insertAtEnd);
#else
        llvm::Instruction *gep =
            llvm::GetElementPtrInst::Create(voidPtr, &indices[0], &indices[2],
                                            "offset_gep", insertAtEnd);
#endif
        if (is32Bit || g->opt.force32BitAddressing)
            return new llvm::PtrToIntInst(gep, LLVMTypes::Int32Type, 
                                          "offset_int", insertAtEnd);
        else
            return new llvm::PtrToIntInst(gep, LLVMTypes::Int64Type, 
                                          "offset_int", insertAtEnd);
    }

    const llvm::TargetData *td = GetTargetMachine()->getTargetData();
    Assert(td != NULL);
    LLVM_TYPE_CONST llvm::StructType *structType = 
        llvm::dyn_cast<LLVM_TYPE_CONST llvm::StructType>(type);
    Assert(structType != NULL);
    const llvm::StructLayout *sl = td->getStructLayout(structType);
    Assert(sl != NULL);

    uint64_t offset = sl->getElementOffset(element);
    if (is32Bit || g->opt.force32BitAddressing)
        return LLVMInt32((int32_t)offset);
    else
        return LLVMInt64(offset);
}
Ejemplo n.º 9
0
		llvm::Value* genTrivialPrimitiveFunctionCall(Function& function, const MethodInfo& methodInfo, PendingResultArray args, llvm::Value* const hintResultValue) {
			auto& module = function.module();
			
			const auto type = methodInfo.parentType;
			const auto methodName = methodInfo.name;
			const auto functionType = methodInfo.functionType;
			const auto& templateArgs = methodInfo.templateArgs;
			
			ConstantGenerator constGen(module);
			TypeGenerator typeGen(module);
			
			switch (type->primitiveID()) {
				case PrimitiveVoid:
					return genVoidPrimitiveMethodCall(function, type, methodName, functionType, std::move(args));
				case PrimitiveCompareResult:
					return genCompareResultPrimitiveMethodCall(function, type, methodName, functionType, std::move(args));
				case PrimitiveNull:
					return genNullPrimitiveMethodCall(function, type, methodName, arrayRef(templateArgs), std::move(args), hintResultValue);
				case PrimitiveBool:
					return genBoolPrimitiveMethodCall(function, type, methodName, functionType, arrayRef(templateArgs), std::move(args), hintResultValue);
				case PrimitiveValueLval:
					return genValueLvalPrimitiveMethodCall(function, type, methodName, functionType, std::move(args), hintResultValue);
				case PrimitiveFinalLval:
					return genFinalLvalPrimitiveMethodCall(function, type, methodName, functionType, std::move(args), hintResultValue);
				case PrimitivePtrLval:
					return genPtrLvalPrimitiveMethodCall(function, type, methodName, functionType, std::move(args), hintResultValue);
				case PrimitivePtr:
					return genPtrPrimitiveMethodCall(function, type, methodName, functionType, std::move(args));
				case PrimitiveFunctionPtr:
				case PrimitiveMethodFunctionPtr:
				case PrimitiveTemplatedFunctionPtr:
				case PrimitiveTemplatedMethodFunctionPtr:
				case PrimitiveVarArgFunctionPtr:
				case PrimitiveMethod:
				case PrimitiveTemplatedMethod:
				case PrimitiveInterfaceMethod:
				case PrimitiveStaticInterfaceMethod:
					return genFunctionPtrPrimitiveMethodCall(function, type, methodName, functionType, std::move(args), hintResultValue);
				case PrimitiveInt8:
				case PrimitiveInt16:
				case PrimitiveInt32:
				case PrimitiveInt64:
				case PrimitiveByte:
				case PrimitiveShort:
				case PrimitiveInt:
				case PrimitiveLong:
				case PrimitiveLongLong:
				case PrimitiveSSize:
				case PrimitivePtrDiff:
					return genSignedIntegerPrimitiveMethodCall(function, type, methodName, functionType, arrayRef(templateArgs), std::move(args), hintResultValue);
				case PrimitiveUInt8:
				case PrimitiveUInt16:
				case PrimitiveUInt32:
				case PrimitiveUInt64:
				case PrimitiveUByte:
				case PrimitiveUShort:
				case PrimitiveUInt:
				case PrimitiveULong:
				case PrimitiveULongLong:
				case PrimitiveSize:
					return genUnsignedIntegerPrimitiveMethodCall(function, type, methodName, functionType, arrayRef(templateArgs), std::move(args), hintResultValue);
				case PrimitiveFloat:
				case PrimitiveDouble:
				case PrimitiveLongDouble:
					return genFloatPrimitiveMethodCall(function, type, methodName, functionType, arrayRef(templateArgs), std::move(args), hintResultValue);
				case PrimitiveTypename:
					return genTypenamePrimitiveMethodCall(function, type, methodName, functionType, std::move(args));
				case PrimitiveRef:
					return genRefPrimitiveMethodCall(function, type, methodName, functionType, std::move(args), hintResultValue);
			}
			
			const auto& typeName = type->getObjectType()->name().last();
			printf("%s\n", typeName.c_str());
			llvm_unreachable("Unknown trivial primitive function.");
		}