public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreation node)
        {
            BoundExpression rewrittenCount = VisitExpression(node.Count);

            // From ILGENREC::genExpr:
            // EDMAURER always perform a checked multiply regardless of the context.
            // localloc takes an unsigned native int. When a user specifies a negative
            // count of elements, per spec, the behavior is undefined. So convert element
            // count to unsigned.

            // NOTE: to match this special case logic, we're going to construct the multiplication
            // ourselves, rather than calling MakeSizeOfMultiplication (which inserts various checks 
            // and conversions).

            TypeSymbol uintType = _factory.SpecialType(SpecialType.System_UInt32);
            TypeSymbol uintPtrType = _factory.SpecialType(SpecialType.System_UIntPtr);

            // Why convert twice?  Because dev10 actually uses an explicit conv_u instruction and the normal conversion
            // from int32 to native uint is emitted as conv_i.  The behavior we want to emulate is to re-interpret
            // (i.e. unchecked) an int32 as unsigned (i.e. uint32) and then convert it to a native uint *without* sign
            // extension.
            BoundExpression convertedCount = _factory.Convert(uintType, rewrittenCount, Conversion.ExplicitNumeric);
            convertedCount = _factory.Convert(uintPtrType, convertedCount, Conversion.IntegerToPointer);

            BoundExpression sizeOfExpression = _factory.Sizeof(((PointerTypeSymbol)node.Type).PointedAtType);
            BinaryOperatorKind multiplicationKind = BinaryOperatorKind.Checked | BinaryOperatorKind.UIntMultiplication; //"UInt" just to make it unsigned
            BoundExpression product = _factory.Binary(multiplicationKind, uintPtrType, convertedCount, sizeOfExpression);

            return node.Update(product, node.Type);
        }
 internal void Parse(BoundStackAllocArrayCreation boundStackAllocArrayCreation)
 {
     base.Parse(boundStackAllocArrayCreation);
     this.Count = Deserialize(boundStackAllocArrayCreation.Count) as Expression;
 }
示例#3
0
 private void EmitStackAllocArrayCreationExpression(BoundStackAllocArrayCreation expression, bool used)
 {
     EmitExpression(expression.Count, used: true);
     _builder.EmitOpCode(ILOpCode.Localloc);
     EmitPopIfUnused(used); //localalloc could overflow the stack, so don't omit, even if used.
 }
示例#4
0
 public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreation node)
 {
     // CLI spec section 3.47 requires that the stack be empty when localloc occurs.
     EnsureOnlyEvalStack();
     return base.VisitStackAllocArrayCreation(node);
 }