Пример #1
0
        /// <summary>
        /// Builds code to invoke the assertion wrapper for debug assertions.
        /// </summary>
        /// <param name="context">The current invocation context.</param>
        /// <param name="condition">The condition to evaluate.</param>
        /// <param name="message">The assertion message.</param>
        /// <param name="file">The current file name.</param>
        /// <param name="line">The line number.</param>
        /// <param name="func">The current function.</param>
        /// <returns>Null.</returns>
        private static Value?MakeAssert(
            InvocationContext context,
            Value condition,
            Value?message,
            string file,
            int line,
            string func)
        {
            var builder = context.Builder;

            var args = new LLVMValueRef[]
            {
                condition.LLVMValue,
                message.HasValue ? message.Value.LLVMValue : BuildGlobalStringPtr(builder, "Assertion Failed", string.Empty),
                BuildGlobalStringPtr(builder, file, string.Empty),
                ConstInt(context.LLVMContext.Int32Type, line, false),
                BuildGlobalStringPtr(builder, func, string.Empty)
            };

            var assertFailedMethod = context.Unit.GetMethod(DebugAssertWrapper);

            BuildCall(
                builder,
                assertFailedMethod.LLVMFunction,
                args);

            return(null);
        }
Пример #2
0
        private Instruction ParseAlloca(LocalId result)
        {
            Expect(TokenType.alloca);
            LLVMType type      = ParseType();
            LLVMType?elcType   = null;
            Value?   elc       = null;
            int      alignment = 0;

            while (PeekAndDiscard(TokenType.COMMA))
            {
                if (Type_FIRST.Contains(Peek().Type))
                {
                    elcType = ParseType();
                    elc     = ParseValue();
                }
                else if (PeekAndDiscard(TokenType.align))
                {
                    alignment = int.Parse(Expect(TokenType.Integer));
                }
            }
            return(new Alloca
            {
                Result = result,
                Type = type,
                ElCountType = elcType,
                ElementCount = elc,
                Alignment = alignment,
            });
        }
Пример #3
0
        public void TestBinaryEncoder()
        {
            BinaryFormatter formatter = new BinaryFormatter();

            Value value = new Value();

            Value?decoded = null;

            MemoryStream ms = new MemoryStream();

            this.Measure(() => {
                formatter.Serialize(ms, value);

                Logger.Log($"Encoded message size: {ms.Length}");

                ms.Seek(0, SeekOrigin.Begin);

                decoded = (Value)formatter.Deserialize(ms);
            }, "BinaryFormatter");

            Assert.AreEqual(value.intVal, decoded?.intVal);
            Assert.AreEqual(value.shortVal, decoded?.shortVal);
            Assert.AreEqual(value.longVal, decoded?.longVal);
            Assert.AreEqual(value.uintVal, decoded?.uintVal);
            Assert.AreEqual(value.ushortVal, decoded?.ushortVal);
            Assert.AreEqual(value.ulongVal, decoded?.ulongVal);
            Assert.AreEqual(value.stringVal, decoded?.stringVal);
            Assert.AreEqual(value.bytesVal, decoded?.bytesVal);
            Assert.AreEqual(value.subValue, decoded?.subValue);
        }
Пример #4
0
        internal static bool CompareWithNulls([NotNullWhen(false)] Value?x, [NotNullWhen(false)] Value?y, out int nullComparisonResult)
        {
            nullComparisonResult = 0;
            bool atLeastOneNull = false;

            // Return -1, 0, or 1 using the null semantics required by IComparable<T>.CompareTo.
            // Any object compares greater than a null reference, and two null references compare
            // equal to each other.
            if (x == null)
            {
                atLeastOneNull = true;
                if (y == null)
                {
                    nullComparisonResult = 0;
                }
                else
                {
                    nullComparisonResult = -1;
                }
            }
            else if (y == null)
            {
                atLeastOneNull       = true;
                nullComparisonResult = 1;
            }

            return(atLeastOneNull);
        }
Пример #5
0
        public override void Visit(ArraySyntax array)
        {
            if (_currentValue != null)
            {
                throw new InvalidOperationException("An Array value must not have an active value.");
            }

            var tomlArray = new ValueList()
            {
                MirrorSyntax = array,
            };
            var items = array.Items;

            for (int i = 0; i < items.ChildrenCount; i++)
            {
                var item = items.GetChildren(i);

                // Visit the child which will set the current value
                item.Accept(this);
                if (_currentValue == null)
                {
                    throw new InvalidOperationException("The current value must be set for Array item");
                }

                // Move the value into the array
                tomlArray.Add(_currentValue);
                _currentValue = null;
            }

            // Set the array as the current value
            _currentValue = new Value(tomlArray);
        }
Пример #6
0
        /// <summary>
        /// Emit IL for the given expression
        /// </summary>
        /// <typeparam name="TInLeft"></typeparam>
        /// <typeparam name="TInRight"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        /// <typeparam name="TEmit"></typeparam>
        /// <param name="expr"></param>
        /// <param name="emitter"></param>
        /// <param name="errorLabel"></param>
        /// <param name="leftConst">Indicates if the left parameter is a constant</param>
        /// <param name="rightConst">Indicates if the right parameter is a constant</param>
        /// <returns>A tuple, indicating the type left on the stack by this expression and if the expression **is** potentially fallible (i.e. errorLabel may be jumped to)</returns>
        public static ConvertResult ConvertBinary <TInLeft, TInRight, TOut, TEmit>(
            this Expression <Func <TInLeft, TInRight, TOut> > expr,
            OptimisingEmitter <TEmit> emitter,
            ExceptionBlock errorLabel,
            Value?leftConst,
            Value?rightConst
            )
        {
            if (expr.ReturnType == typeof(StaticError))
            {
                return(new ConvertResult(typeof(StaticError), null, null));
            }

            // Try to convert expression without putting things into locals. Only works with certain expressions.
            var fast = TryConvertBinaryFastPath(expr, emitter, errorLabel, leftConst, rightConst);

            if (fast != null)
            {
                return(fast.Value);
            }

            // Put the parameters into local, ready to be used later
            using var localRight = emitter.DeclareLocal(typeof(TInRight), "ConvertBinary_Right", false);
            emitter.StoreLocal(localRight);
            using var localLeft = emitter.DeclareLocal(typeof(TInLeft), "ConvertBinary_Left", false);
            emitter.StoreLocal(localLeft);
            var parameters = new Dictionary <string, Parameter> {
                { expr.Parameters[0].Name !, new Parameter(localLeft, leftConst) },
Пример #7
0
        private void SetValuesFromProviders(string path, Type type, IDictionary <string, object> obj)
        {
            var propertyInfos = ReflectionUtils.GetProperties(type);

            foreach (var property in propertyInfos)
            {
                var propertyPath = path + "." + property.Name;

                if (ReflectionUtils.IsNestedParameterProperty(property))
                {
                    SetValuesFromProviders(propertyPath, property.PropertyType,
                                           obj[property.Name] as IDictionary <string, object>);
                    continue;
                }

                Value?value = null;
                foreach (var provider in _valueProviders)
                {
                    value = provider.GetValue(propertyPath);
                    if (value != null)
                    {
                        break;
                    }
                }

                if (value == null)
                {
                    continue;
                }

                obj[property.Name] = ValueDeserialiser.GetValue(value.Value.ValueToSet, property.PropertyType,
                                                                property.Name, "setting value from value provider");
                obj[property.Name + Consts.SourceMetadata] = value.Value.SourceHint;
            }
        }
Пример #8
0
 public override void Visit(FloatValueSyntax floatValueSyntax)
 {
     if (_currentValue != null)
     {
         throw new InvalidOperationException("A Float value must be at a leaf.");
     }
     _currentValue = new Value(floatValueSyntax.Value);
 }
Пример #9
0
 public override void Visit(StringValueSyntax stringValue)
 {
     if (_currentValue != null)
     {
         throw new InvalidOperationException("A String value must be at a leaf.");
     }
     _currentValue = new Value(stringValue.Value);
 }
Пример #10
0
 public override void Visit(BooleanValueSyntax boolValue)
 {
     if (_currentValue != null)
     {
         throw new InvalidOperationException("A Boolean value must be at a leaf.");
     }
     _currentValue = new Value(boolValue.Value);
 }
Пример #11
0
 public override void Visit(IntegerValueSyntax integerValueSyntax)
 {
     if (_currentValue != null)
     {
         throw new InvalidOperationException("An Integer value must be at a leaf.");
     }
     _currentValue = new Value(integerValueSyntax.Value);
 }
Пример #12
0
 /// <summary>
 /// Creates a new array value from the given opaque array of elements of the given type.
 /// </summary>
 /// <param name="array">The opaque pointer to the array data structure</param>
 /// <param name="length">Value of type i64 indicating the number of elements in the array; will be computed on demand if the given value is null</param>
 /// <param name="elementType">Q# type of the array elements</param>
 /// <param name="context">Generation context where constants are defined and generated if needed</param>
 internal ArrayValue(Value array, Value?length, ResolvedType elementType, GenerationContext context)
 {
     this.sharedState       = context;
     this.QSharpElementType = elementType;
     this.LlvmElementType   = context.LlvmTypeFromQsharpType(elementType);
     this.OpaquePointer     = Types.IsArray(array.NativeType) ? array : throw new ArgumentException("expecting an opaque array");
     this.length            = length == null
         ? new IValue.Cached <Value>(context, this.GetLength)
         : this.CreateLengthCache(length);
 }
Пример #13
0
            public T?FromValue(Value?value, object parent)
            { // lots of casting here, but it works i promise (probably) (parent can be a non-IGeneratedStore, however it won't necessarily behave then)
                if (value is null)
                {
                    return(null);
                }
                var obj = Create(parent as GeneratedStoreImpl.IGeneratedStore);

                obj.Deserialize(value);
                return(obj);
            }
Пример #14
0
 public SerializableValue(
     int first     = 0,
     string?second = default,
     Value?third   = default,
     IEnumerable <string>?fourth = default)
 {
     First  = first;
     Second = second;
     Third  = third;
     Fourth = fourth.Snapshot();
 }
Пример #15
0
        public static Value Subtract(Value x, Value y, Calculator calc)
        {
            Value?result = null;

            if (HandleImplicitTypeConversion(ref x, ref y))
            {
                switch (x.ValueType)
                {
                case RpnValueType.Binary:
                    result = BinaryValue.Subtract((BinaryValue)x, (BinaryValue)y, calc);
                    break;

                case RpnValueType.Complex:
                    result = (ComplexValue)x - (ComplexValue)y;
                    break;

                case RpnValueType.DateTime:
                    result = (DateTimeValue)x - (DateTimeValue)y;
                    break;

                case RpnValueType.Double:
                    result = (DoubleValue)x - (DoubleValue)y;
                    break;

                case RpnValueType.Fraction:
                    result = (FractionValue)x - (FractionValue)y;
                    break;

                case RpnValueType.Integer:
                    result = (IntegerValue)x - (IntegerValue)y;
                    break;

                case RpnValueType.TimeSpan:
                    result = (TimeSpanValue)x - (TimeSpanValue)y;
                    break;
                }
            }
            else
            {
                // Handle special cases.
                if (x.ValueType == RpnValueType.DateTime && y.ValueType == RpnValueType.TimeSpan)
                {
                    result = (DateTimeValue)x - (TimeSpanValue)y;
                }
            }

            if (result == null)
            {
                throw InvalidOp(Resources.Value_Subtract, x, y);
            }

            return(result);
        }
Пример #16
0
        public override void Visit(InlineTableSyntax inlineTable)
        {
            var parentTable = _currentTable;

            _currentTable = new ValueTable()
            {
                MirrorSyntax = inlineTable,
            };
            base.Visit(inlineTable);
            _currentValue = new Value(_currentTable);
            _currentTable = parentTable;
        }
Пример #17
0
 /// <summary>
 /// Tries to handle a method invocation in a custom device-function handler.
 /// </summary>
 /// <param name="context">The invocation context.</param>
 /// <param name="result">The resulting stack value.</param>
 /// <returns>True, iff the method was handled successfully.</returns>
 internal bool HandleIntrinsic(InvocationContext context, out Value?result)
 {
     for (int i = 0, e = deviceFunctions.Count; i < e; ++i)
     {
         var function = deviceFunctions[i];
         if (function.Handle(context, out result))
         {
             return(true);
         }
     }
     result = null;
     return(false);
 }
Пример #18
0
        public static Value Multiply(Value x, Value y, Calculator calc)
        {
            Value?result = null;

            if (HandleImplicitTypeConversion(ref x, ref y))
            {
                switch (x.ValueType)
                {
                case RpnValueType.Binary:
                    result = BinaryValue.Multiply((BinaryValue)x, (BinaryValue)y, calc);
                    break;

                case RpnValueType.Complex:
                    result = (ComplexValue)x * (ComplexValue)y;
                    break;

                case RpnValueType.Double:
                    result = (DoubleValue)x * (DoubleValue)y;
                    break;

                case RpnValueType.Fraction:
                    result = (FractionValue)x * (FractionValue)y;
                    break;

                case RpnValueType.Integer:
                    result = (IntegerValue)x * (IntegerValue)y;
                    break;
                }
            }
            else
            {
                // Handle special cases.
                if (x.ValueType == RpnValueType.TimeSpan && y is NumericValue numY)
                {
                    // TimeSpan * Numeric
                    result = (TimeSpanValue)x * new DoubleValue(numY.ToDouble());
                }
                else if (x is NumericValue numX && y.ValueType == RpnValueType.TimeSpan)
                {
                    // Numeric * TimeSpan
                    result = (TimeSpanValue)y * new DoubleValue(numX.ToDouble());
                }
            }

            if (result == null)
            {
                throw InvalidOp(Resources.Value_Multiply, x, y);
            }

            return(result);
        }
Пример #19
0
        public static void Remove(IList <Value> container, Value?data)
        {
            if (data == null)
            {
                return;
            }

            if (container.All(c => c.SomeField != data.SomeField))
            {
                return;
            }

            container.Remove(data); // очень много связанной логики и т.п.
        }
Пример #20
0
 public TestObject1(Value?v, string?d, bool isv, bool isl, decimal o,
                    string?il, string?t, string?im,
                    ImmutableArray <CustomProperty>?cu)
 {
     V   = v;
     S   = v.ToString();
     D   = d ?? S;
     IsV = isv;
     IsL = isl;
     O   = o;
     Im  = il;
     T   = t;
     In  = im;
     Cu  = cu;
 }
Пример #21
0
        /// <summary>
        /// Creates a pointer that can store a value and provides a caching mechanism for accessing that value
        /// to avoid unnecessary loads. The pointer is instantiated with the given pointer.
        /// If the given pointer is null, a new pointer is created via an alloca instruction.
        /// </summary>
        /// <param name="pointer">Optional parameter to provide an existing pointer to use</param>
        /// <param name="type">The Q# type of the value that the pointer points to</param>
        /// <param name="context">Generation context where constants are defined and generated if needed</param>
        internal PointerValue(Value?pointer, ResolvedType type, GenerationContext context)
        {
            void Store(IValue v) =>
            context.CurrentBuilder.Store(v.Value, this.pointer);

            IValue Reload() =>
            context.Values.From(
                context.CurrentBuilder.Load(this.LlvmType, this.pointer),
                this.QSharpType);

            this.QSharpType  = type;
            this.LlvmType    = context.LlvmTypeFromQsharpType(this.QSharpType);
            this.pointer     = pointer ?? context.CurrentBuilder.Alloca(this.LlvmType);
            this.cachedValue = new IValue.Cached <IValue>(context, Reload, Store);
        }
        protected override void SetRawValue(string?rawValue)
        {
            _rawValue = rawValue;
            _values.Clear();
            var managedValues = GetManagedValues().ToList();

            var position = 0;

            var managedValuesInfo = new List <ManagedValueInfo>();

            foreach (var managedValue in managedValues)
            {
                managedValuesInfo.Add(new ManagedValueInfo {
                    Value = managedValue, Parsed = false
                });
                managedValue.Reset();
                managedValue.ActualPosition = position++;
            }

            _values.AddRange(managedValues);

            if (rawValue == null)
            {
                return;
            }

            foreach (var parsedValue in HeaderValuesParser.ParseStatic(rawValue, ValuesDelimiter))
            {
                Value?value = null;

                foreach (var managedValueInfo in managedValuesInfo)
                {
                    if (!managedValueInfo.Parsed && managedValueInfo.Value.Parse(parsedValue.Interpreted, parsedValue.Raw))
                    {
                        managedValueInfo.Parsed = true;
                        value = managedValueInfo.Value;
                        break;
                    }
                }

                if (value == null)
                {
                    value = new UnmanagedValue(parsedValue.Raw);
                    _values.Add(value);
                }
                value.ActualPosition = position++;
            }
        }
Пример #23
0
        public static void RemoveThird(IList <Value> container, Value?data)
        {
            if (data == null)
            {
                return;
            }

            var deleteT = container.SingleOrDefault(c => c.SomeField == data.SomeField);

            if (deleteT == null)
            {
                return;
            }

            container.Remove(deleteT);
        }
Пример #24
0
        private Instruction ParseRet()
        {
            Expect(TokenType.ret);
            var   type = ParseType();
            Value?val  = null;

            if (type != LLVMType.Void)
            {
                val = ParseValue();
            }
            return(new RetInstr
            {
                Type = type,
                Value = val,
            });
        }
Пример #25
0
        internal static Value?Load(INode valueNode, Calculator calc)
        {
            Value?result = null;

            if (valueNode != null)
            {
                string?typeText  = valueNode.GetValueN(nameof(ValueType), null);
                string?valueText = valueNode.GetValueN("EntryValue", null);

                if (typeText != null && valueText != null)
                {
                    if (Enum.TryParse(typeText, false, out RpnValueType type))
                    {
                        TryParse(type, valueText, calc, out result);
                    }
                }
            }

            return(result);
        }
Пример #26
0
        public override void Visit(KeyValueSyntax keyValue)
        {
            if (_currentValue != null)
            {
                throw new InvalidOperationException("An KeyValue value must not have an active value.");
            }

            // Visit the key value, which will place the converted value into the current value
            keyValue.Value.Accept(this);
            if (_currentValue == null)
            {
                throw new InvalidOperationException("The current value must be set for KeyValue");
            }

            // Resolve the key
            var(currentTable, valueName) = ResolveKey(keyValue.Key);

            // Move the value into the reference
            currentTable[valueName] = _currentValue;
            _currentValue           = null;
        }
        /// <summary>
        /// Tries to handle the given invocation context in the scope of these compiler-known functions.
        /// </summary>
        /// <param name="context">The current invocation context.</param>
        /// <param name="result">The resulting value.</param>
        /// <returns>True, iff this context can handle the curent invocation context.</returns>
        public bool Handle(InvocationContext context, out Value?result)
        {
            result = null;

            var intrinsic = context.Method.GetCustomAttribute <IntrinsicAttribute>();

            // Check custom intrinsics
            if (intrinsic != null)
            {
                if (!IntrinsicDeviceFunctionHandlers.TryGetValue(
                        intrinsic.Type,
                        out IntrinsicDeviceFunctionHandler intrinsicHandler))
                {
                    throw context.CompilationContext.GetNotSupportedException(
                              ErrorMessages.NotSupportedIntrinsic, intrinsic.Type);
                }
                result = intrinsicHandler(this, context, intrinsic);
                return(true);
            }

            // Check for intrinsic activator functionality
            if (context.Method.DeclaringType == typeof(Activator))
            {
                result = MakeActivatorCall(context);
                return(true);
            }

            // Check external intrinsic functions
            if (!DeviceFunctionHandlers.TryGetValue(context.Method, out DeviceFunctionHandler handler))
            {
                return(false);
            }

            result = handler(this, context);
            return(true);
        }
Пример #28
0
 // IEquatable
 public abstract bool Equals(Value?other);
Пример #29
0
 public abstract InvokeResult CallMethod(MethodMirror method, Value?obj, IList <Value> arguments, FuncEvalOptions options);
Пример #30
0
        InvokeResult CallCore(MethodMirror method, Value?obj, IList <Value> arguments, FuncEvalOptions options, bool isNewobj)
        {
            if (evalTimedOut)
            {
                throw new TimeoutException();
            }

            IInvokeAsyncResult?asyncRes = null;
            bool done = false;

            try {
                funcEvalState.isEvaluatingCounter++;

                var currTime = DateTime.UtcNow;
                var timeLeft = endTime - currTime;
                if (timeLeft >= TimeSpan.Zero)
                {
                    funcEvalState.methodInvokeCounter++;

                    Debug2.Assert(!isNewobj || obj is null);
                    bool isInvokeInstanceMethod = obj is not null && !isNewobj;

                    AsyncCallback asyncCallback = asyncRes2 => {
                        if (done)
                        {
                            return;
                        }
                        InvokeResult resTmp;
                        try {
                            if (isInvokeInstanceMethod)
                            {
                                resTmp = obj !.EndInvokeMethodWithResult(asyncRes2);
                            }
                            else
                            {
                                resTmp = method.DeclaringType.EndInvokeMethodWithResult(asyncRes2);
                            }
                            debugMessageDispatcher.CancelDispatchQueue(resTmp);
                        }
                        catch (Exception ex) {
                            debugMessageDispatcher.CancelDispatchQueue(ExceptionDispatchInfo.Capture(ex));
                        }
                    };

                    if (isInvokeInstanceMethod)
                    {
                        asyncRes = obj !.BeginInvokeMethod(thread, method, arguments, GetInvokeOptions(options), asyncCallback, null);
                    }
                    else
                    {
                        asyncRes = method.DeclaringType.BeginInvokeMethod(thread, method, arguments, GetInvokeOptions(options), asyncCallback, null);
                    }

                    var res = debugMessageDispatcher.DispatchQueue(timeLeft, out bool timedOut);
                    if (timedOut)
                    {
                        evalTimedOut = true;
                        try {
                            asyncRes.Abort();
                        }
                        catch (CommandException ce) when(ce.ErrorCode == ErrorCode.ERR_NO_INVOCATION)
                        {
                        }
                        throw new TimeoutException();
                    }
                    if (res is ExceptionDispatchInfo exInfo)
                    {
                        exInfo.Throw();
                    }
                    Debug.Assert(res is InvokeResult);
                    return(res as InvokeResult ?? throw new InvalidOperationException());
                }
                else
                {
                    evalTimedOut = true;
                    throw new TimeoutException();
                }
            }
            finally {
                done = true;
                funcEvalState.isEvaluatingCounter--;
                asyncRes?.Dispose();
            }
        }