Beispiel #1
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(
                    ));
        }