Пример #1
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 1)
            {
                throw new StackTooSmallException(OpCode.SetGlobal, 1, stack.Count);
            }

            CompileIKVM.GlobalInfo setter;
            try
            {
                setter = context.GlobalSetters[this.Index];
            }
            catch (System.IndexOutOfRangeException x)
            {
                throw new CompilerException($"Global at index {this.Index} does not exist.", x);
            }

            if (setter == null)
            {
                throw new CompilerException($"Global at index {this.Index} is immutable.");
            }

            var type = stack.Pop();

            if (type != setter.Type)
            {
                throw new StackTypeInvalidException(OpCode.SetGlobal, setter.Type, type);
            }

            context.EmitLoadThis();
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, setter.Builder);
        }
Пример #2
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            if (context.GlobalGetters == null)
            {
                throw new CompilerException("Can't use GetGlobal without a global section.");
            }

            CompileIKVM.GlobalInfo getter;
            try
            {
                getter = context.GlobalGetters[this.Index];
            }
            catch (System.IndexOutOfRangeException x)
            {
                throw new CompilerException($"Global at index {this.Index} does not exist.", x);
            }

            if (getter.IsMutable)
            {
                context.EmitLoadThis();
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, getter.Builder);

            context.Stack.Push(getter.Type);
        }
Пример #3
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 2)
            {
                throw new StackTooSmallException(this.OpCode, 2, stack.Count);
            }

            var type = stack.Pop();

            if (type != this.Type)
            {
                throw new StackTypeInvalidException(this.OpCode, this.Type, type);
            }

            type = stack.Pop();
            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(this.OpCode, ValueType.Int32, type);
            }

            Int32Constant.Emit(context, (int)this.Offset);
            context.EmitLoadThis();
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, this.IKVMCreateStoreMethod(this.StoreHelper, context, universe));
        }
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count == 0)
            {
                throw new StackTooSmallException(this.OpCode, 1, 0);
            }

            var type = stack.Pop();

            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(this.OpCode, ValueType.Int32, type);
            }

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

            this.IKVMEmitRangeCheck(context, universe);

            context.EmitLoadThis();
            context.Emit(IKVM.Reflection.Emit.OpCodes.Ldfld, context.Memory);
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, Runtime.UnmanagedMemory.IKVMStartGetter(universe));
            context.Emit(IKVM.Reflection.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;
            }

            if (alignment != 4)
            {
                context.Emit(IKVM.Reflection.Emit.OpCodes.Unaligned, alignment);
            }

            context.Emit(this.IKVMEmittedOpCode);
            var conversion = this.IKVMConversionOpCode;

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

            stack.Push(this.Type);
        }
Пример #5
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var signature   = context.Types[this.Type];
            var paramTypes  = signature.RawParameterTypes;
            var returnTypes = signature.RawReturnTypes;

            var stack = context.Stack;

            if (stack.Count < paramTypes.Length)
            {
                throw new StackTooSmallException(OpCode.CallIndirect, paramTypes.Length, stack.Count);
            }

            var type = stack.Pop();

            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(OpCode.CallIndirect, ValueType.Int32, type);
            }

            for (var i = paramTypes.Length - 1; i >= 0; i--)
            {
                type = stack.Pop();
                if (type != paramTypes[i])
                {
                    throw new StackTypeInvalidException(OpCode.CallIndirect, paramTypes[i], type);
                }
            }

            for (var i = 0; i < returnTypes.Length; i++)
            {
                stack.Push(returnTypes[i]);
            }

            Int32Constant.Emit(context, checked ((int)this.Type));
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.GetFunctionPointer]);
            context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc, context.IndirectPointerLocal.LocalIndex);
            context.EmitLoadThis();
            context.Emit(IKVM.Reflection.Emit.OpCodes.Ldloc, context.IndirectPointerLocal.LocalIndex);
            context.EmitCalli(
                signature.IKVMReturnTypes.Length == 0 ? universe.Import(typeof(void)) : signature.IKVMReturnTypes[0],
                signature.IKVMParameterTypes.Concat(new[] { context.ExportsBuilder.AsType() }).ToArray(
                    ));
        }
Пример #6
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            if (this.Index >= context.Methods.Length)
            {
                throw new CompilerException($"Function for index {this.Index} requseted, the assembly contains only {context.Methods.Length}.");
            }

            var signature   = context.FunctionSignatures[this.Index];
            var paramTypes  = signature.RawParameterTypes;
            var returnTypes = signature.RawReturnTypes;

            var stack = context.Stack;

            if (stack.Count < paramTypes.Length)
            {
                throw new StackTooSmallException(this.OpCode, paramTypes.Length, stack.Count);
            }

            for (var i = paramTypes.Length - 1; i >= 0; i--)
            {
                var type = stack.Pop();
                if (type != paramTypes[i])
                {
                    throw new StackTypeInvalidException(this.OpCode, paramTypes[i], type);
                }
            }

            for (var i = 0; i < returnTypes.Length; i++)
            {
                stack.Push(returnTypes[i]);
            }

            var target = context.Methods[this.Index];

            if (target is IKVM.Reflection.Emit.MethodBuilder) //Indicates a dynamically generated method.
            {
                context.EmitLoadThis();
            }
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, target);
        }