internal sealed override void Compile(CompilationContext context)
    {
        context.PopStackNoReturn(this.OpCode, this.Type, WebAssemblyValueType.Int32);

        Int32Constant.Emit(context, (int)this.Offset);
        context.EmitLoadThis();
        context.Emit(OpCodes.Call, context[this.StoreHelper, this.CreateStoreMethod]);
    }
Esempio n. 2
0
    internal sealed override void Compile(CompilationContext context)
    {
        var stack = context.Stack;

        context.PopStackNoReturn(this.OpCode, WebAssemblyValueType.Int32);

        if (this.Offset != 0)
        {
            Int32Constant.Emit(context, (int)this.Offset);
            context.Emit(OpCodes.Add_Ovf_Un);
        }

        this.EmitRangeCheck(context);

        context.EmitLoadThis();
        context.Emit(OpCodes.Ldfld, context.CheckedMemory);
        context.Emit(OpCodes.Call, UnmanagedMemory.StartGetter);
        context.Emit(OpCodes.Add);

        byte alignment;

        switch (this.Flags & Options.Align8)
        {
        default:     //Impossible to hit, but needed to avoid compiler error the about alignment variable.
        case Options.Align1: alignment = 1; break;

        case Options.Align2: alignment = 2; break;

        case Options.Align4: alignment = 4; break;

        case Options.Align8: alignment = 8; break;
        }

        //8-byte alignment is not available in IL.
        //See: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.unaligned?view=net-5.0
        //However, because 8-byte alignment is subset of 4-byte alignment,
        //We don't have to consider it.
        if (alignment != 4 && alignment != 8)
        {
            context.Emit(OpCodes.Unaligned, alignment);
        }

        context.Emit(this.EmittedOpCode);
        var conversion = this.ConversionOpCode;

        if (conversion != OpCodes.Nop)
        {
            context.Emit(conversion);
        }

        stack.Push(this.Type);
    }