예제 #1
0
        public void InitializeStateType(Module module, string functionName)
        {
            var stateFieldTypes = new List <LLVMTypeRef>();

            // fixed fields
            stateFieldTypes.Add(FunctionCompletionStatusType(Context)); // function completion status: 0 = not done, 1 = completed successfully, 2 = panic
            stateFieldTypes.Add(Context.WakerType());                   // caller waker
            // end fixed fields
            stateFieldTypes.AddRange(_stateFields.Select(a => Context.AsLLVMType(a.Type)));
            StateType = Context.NamedStructType(functionName + "_state_t", stateFieldTypes.ToArray());
        }
예제 #2
0
        internal static LLVMTypeRef TranslateParameterType(this ContextWrapper context, NIType parameterType)
        {
            // TODO: this should probably share code with how we compute the top function LLVM type above
            bool isInput  = parameterType.GetInputParameterPassingRule() != NIParameterPassingRule.NotAllowed,
                 isOutput = parameterType.GetOutputParameterPassingRule() != NIParameterPassingRule.NotAllowed;
            LLVMTypeRef parameterLLVMType = context.AsLLVMType(parameterType.GetDataType());

            if (isInput)   // includes inout parameters
            {
                if (isOutput && !parameterType.GetDataType().IsRebarReferenceType())
                {
                    throw new InvalidOperationException("Inout parameter with non-reference type");
                }
                return(parameterLLVMType);
            }
            if (isOutput)
            {
                return(LLVMTypeRef.PointerType(parameterLLVMType, 0u));
            }
            throw new NotImplementedException("Parameter direction is wrong");
        }
예제 #3
0
        // TechDebt: for some of the types below, it would be nicer to return named types, which we can do now that we're
        // passing around an LLVM context.
        public static LLVMTypeRef AsLLVMType(this ContextWrapper context, NIType niType)
        {
            switch (niType.GetKind())
            {
            case NITypeKind.UInt8:
            case NITypeKind.Int8:
                return(context.Int8Type);

            case NITypeKind.UInt16:
            case NITypeKind.Int16:
                return(context.Int16Type);

            case NITypeKind.UInt32:
            case NITypeKind.Int32:
                return(context.Int32Type);

            case NITypeKind.UInt64:
            case NITypeKind.Int64:
                return(context.Int64Type);

            case NITypeKind.Boolean:
                return(context.Int1Type);

            case NITypeKind.String:
                return(context.StringType());

            default:
            {
                if (niType.IsRebarReferenceType())
                {
                    NIType referentType = niType.GetReferentType();
                    if (referentType == DataTypes.StringSliceType)
                    {
                        return(context.StringSliceReferenceType());
                    }
                    NIType sliceElementType;
                    if (referentType.TryDestructureSliceType(out sliceElementType))
                    {
                        return(context.CreateLLVMSliceReferenceType(context.AsLLVMType(sliceElementType)));
                    }
                    return(LLVMTypeRef.PointerType(context.AsLLVMType(referentType), 0u));
                }
                if (niType.IsCluster())
                {
                    LLVMTypeRef[] fieldTypes = niType.GetFields().Select(field => context.AsLLVMType(field.GetDataType())).ToArray();
                    return(context.StructType(fieldTypes));
                }
                if (niType == DataTypes.FileHandleType)
                {
                    return(context.FileHandleType());
                }
                if (niType == DataTypes.FakeDropType)
                {
                    return(context.FakeDropType());
                }
                if (niType == DataTypes.RangeIteratorType)
                {
                    return(context.RangeIteratorType());
                }
                if (niType == DataTypes.WakerType)
                {
                    return(context.WakerType());
                }
                NIType innerType;
                if (niType.TryDestructureOptionType(out innerType))
                {
                    return(context.CreateLLVMOptionType(context.AsLLVMType(innerType)));
                }
                if (niType.IsStringSplitIteratorType())
                {
                    return(context.StringSplitIteratorType());
                }
                if (niType.TryDestructureVectorType(out innerType))
                {
                    return(context.CreateLLVMVectorType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureSliceIteratorType(out innerType) ||
                    niType.TryDestructureSliceMutableIteratorType(out innerType))
                {
                    return(context.CreateLLVMSliceIteratorType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureSharedType(out innerType))
                {
                    return(context.CreateLLVMSharedType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureYieldPromiseType(out innerType))
                {
                    return(context.CreateLLVMYieldPromiseType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureMethodCallPromiseType(out innerType))
                {
                    return(context.CreateLLVMMethodCallPromiseType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureNotifierReaderType(out innerType))
                {
                    return(context.CreateLLVMNotifierReaderType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureNotifierReaderPromiseType(out innerType))
                {
                    return(context.CreateLLVMNotifierReaderPromiseType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructureNotifierWriterType(out innerType))
                {
                    return(context.CreateLLVMNotifierWriterType(context.AsLLVMType(innerType)));
                }
                if (niType.TryDestructurePanicResultType(out innerType))
                {
                    return(context.CreateLLVMPanicResultType(context.AsLLVMType(innerType)));
                }
                // TODO: when using typedef classes and unions in FunctionCompiler, the LLVM type should
                // come from a TypeDiagramBuiltPackage.
                if (niType.IsValueClass() && niType.GetFields().Any())
                {
                    LLVMTypeRef[] fieldTypes = niType.GetFields().Select(f => context.AsLLVMType(f.GetDataType())).ToArray();
                    return(context.StructType(fieldTypes));
                }
                if (niType.IsUnion())
                {
                    int maxSize = 4;
                    foreach (NIType field in niType.GetFields())
                    {
                        // TODO: where possible, use a non-array type that matches the max size
                        LLVMTypeRef llvmFieldType = context.AsLLVMType(field.GetDataType());
                        int         fieldSize     = (int)LLVMSharp.LLVM.StoreSizeOfType(LocalTargetInfo.TargetData, llvmFieldType);
                        maxSize = Math.Max(maxSize, fieldSize);
                    }
                    LLVMTypeRef[] structFieldTypes = new LLVMTypeRef[]
                    {
                        context.Int8Type,
                        // TODO: this is incorrect because it does not consider alignment
                        LLVMTypeRef.ArrayType(context.Int8Type, (uint)maxSize)
                    };
                    return(context.StructType(structFieldTypes));
                }
                throw new NotSupportedException("Unsupported type: " + niType);
            }
            }
        }