示例#1
0
        protected override void compile(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentILGenerator;

            // find constructor
            var type = FunctionalHelper.CreateDelegateType(Body.GetExpressionType(ctx), _Method.ArgumentTypes);
            var ctor = ctx.ResolveConstructor(type, new[] {typeof (object), typeof (IntPtr)});

            var closureInstance = ctx.CurrentScope.ClosureVariable;
            gen.EmitLoadLocal(closureInstance);
            gen.EmitLoadFunctionPointer(_Method.MethodBuilder);
            gen.EmitCreateObject(ctor.ConstructorInfo);
        }
示例#2
0
        protected override void compile(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentILGenerator;

            var type = GetExpressionType(ctx);
            if(type.IsVoid())
                Error(CompilerMessages.VoidTypeDefault);

            if(type.IsAbstract)
                Error(CompilerMessages.TypeAbstract, TypeSignature.FullSignature);

            if(Arguments.Count == 0)
                Error(CompilerMessages.ParameterlessConstructorParens);

            var isParameterless = Arguments.Count == 1 && Arguments[0].GetExpressionType(ctx) == typeof (Unit);

            var argTypes = isParameterless
                ? Type.EmptyTypes
                : Arguments.Select(a => a.GetExpressionType(ctx)).ToArray();

            try
            {
                var ctor = ctx.ResolveConstructor(type, argTypes);

                if (!isParameterless)
                {
                    var destTypes = ctor.ArgumentTypes;
                    for (var idx = 0; idx < Arguments.Count; idx++)
                        Expr.Cast(Arguments[idx], destTypes[idx]).Compile(ctx, true);
                }

                gen.EmitCreateObject(ctor.ConstructorInfo);
            }
            catch (AmbiguousMatchException)
            {
                Error(CompilerMessages.TypeConstructorAmbiguos, TypeSignature.FullSignature);
            }
            catch (KeyNotFoundException)
            {
                if (!isParameterless || !type.IsValueType)
                    Error(CompilerMessages.TypeConstructorNotFound, TypeSignature.FullSignature);

                var castExpr = Expr.Default(TypeSignature);
                castExpr.Compile(ctx, true);
            }
        }
示例#3
0
        protected override void emitCode(Context ctx, bool mustReturn)
        {
            var resultType = Resolve(ctx);

            var gen = ctx.CurrentMethod.Generator;

            // local name is not cached because it can be closured.
            // if the identifier is actually a local constant, the 'compile' method is not invoked at all
            var local = Local ?? ctx.Scope.FindLocal(Identifier);
            if (local != null)
            {
                if(local.IsImmutable && RefArgumentRequired)
                    error(CompilerMessages.ConstantByRef);

                if (local.IsClosured)
                {
                    if (local.ClosureDistance == 0)
                        emitGetClosuredLocal(ctx, local);
                    else
                        emitGetClosuredRemote(ctx, local);
                }
                else
                {
                    emitGetLocal(ctx, local);
                }

                return;
            }

            // load pointer to global function
            if (_Method != null)
            {
                var ctor = ctx.ResolveConstructor(resultType, new[] {typeof (object), typeof (IntPtr)});

                gen.EmitNull();
                gen.EmitLoadFunctionPointer(_Method.MethodInfo);
                gen.EmitCreateObject(ctor.ConstructorInfo);

                return;
            }

            // get a property value
            if (_Property != null)
            {
                var id = _Property.PropertyId;
                if(!_Property.HasGetter)
                    error(CompilerMessages.GlobalPropertyNoGetter, Identifier);

                var type = _Property.PropertyType;
                if (_Property.GetterMethod != null)
                {
                    gen.EmitCall(_Property.GetterMethod.MethodInfo);
                }
                else
                {
                    var method = typeof (GlobalPropertyHelper).GetMethod("Get").MakeGenericMethod(type);
                    gen.EmitConstant(ctx.ContextId);
                    gen.EmitConstant(id);
                    gen.EmitCall(method);
                }
                return;
            }

            error(CompilerMessages.IdentifierNotFound, Identifier);
        }
示例#4
0
        private void castDelegate(Context ctx, Type from, Type to)
        {
            var gen = ctx.CurrentILGenerator;

            var toCtor = ctx.ResolveConstructor(to, new[] {typeof (object), typeof (IntPtr)});
            var fromMethod = ctx.ResolveMethod(from, "Invoke");
            var toMethod = ctx.ResolveMethod(to, "Invoke");

            var fromArgs = fromMethod.ArgumentTypes;
            var toArgs = toMethod.ArgumentTypes;

            if(fromArgs.Length != toArgs.Length || toArgs.Select((ta, id) => !ta.IsExtendablyAssignableFrom(fromArgs[id], true)).Any(x => x))
                Error(CompilerMessages.CastDelegateArgTypesMismatch, from, to);

            if(!toMethod.ReturnType.IsExtendablyAssignableFrom(fromMethod.ReturnType, true))
                Error(CompilerMessages.CastDelegateReturnTypesMismatch, from, to);

            if (fromMethod.IsStatic)
                gen.EmitNull();
            else
                Expression.Compile(ctx, true);

            if (from.IsGenericType && to.IsGenericType && from.GetGenericTypeDefinition() == to.GetGenericTypeDefinition())
                return;

            gen.EmitLoadFunctionPointer(fromMethod.MethodInfo);
            gen.EmitCreateObject(toCtor.ConstructorInfo);
        }
示例#5
0
        protected override Type resolve(Context ctx, bool mustReturn)
        {
            base.resolve(ctx, true);

            var type = Type ?? ctx.ResolveType(TypeSignature);

            if (type.IsVoid())
                error(CompilerMessages.VoidTypeDefault);

            if (type.IsAbstract)
                error(CompilerMessages.TypeAbstract, TypeSignature.FullSignature);

            if (type.IsInterface)
                error(CompilerMessages.TypeInterface, TypeSignature.FullSignature);

            if (Arguments.Count == 0)
                error(CompilerMessages.ParameterlessConstructorParens);

            try
            {
                _Constructor = ctx.ResolveConstructor(type, _ArgTypes);
            }
            catch (AmbiguousMatchException)
            {
                error(CompilerMessages.TypeConstructorAmbiguos, TypeSignature.FullSignature);
            }
            catch (KeyNotFoundException)
            {
                if (_ArgTypes.Length > 0 || !type.IsValueType)
                    error(CompilerMessages.TypeConstructorNotFound, TypeSignature.FullSignature);

                _IsDefault = true;
                return type;
            }

            applyLambdaArgTypes(ctx);

            return resolvePartial(_Constructor, type, _ArgTypes);
        }
示例#6
0
        private void compileComposition(Context ctx)
        {
            var gen = ctx.CurrentILGenerator;

            // find constructor
            var type = FunctionalHelper.CreateDelegateType(_Method.ReturnType, _Method.ArgumentTypes);
            var ctor = ctx.ResolveConstructor(type, new[] { typeof(object), typeof(IntPtr) });

            var closureInstance = ctx.CurrentScope.ClosureVariable;
            gen.EmitLoadLocal(closureInstance);
            gen.EmitLoadFunctionPointer(_Method.MethodBuilder);
            gen.EmitCreateObject(ctor.ConstructorInfo);
        }
示例#7
0
        /// <summary>
        /// Emits code for getting the method as a delegate instance.
        /// </summary>
        private void emitMethod(Context ctx, ILGenerator gen)
        {
            if (RefArgumentRequired)
                error(CompilerMessages.MethodRef);

            if (_IsStatic)
                gen.EmitNull();

            var retType = _Method.ReturnType;
            var type = retType.IsVoid()
                ? FunctionalHelper.CreateActionType(_Method.ArgumentTypes)
                : FunctionalHelper.CreateFuncType(retType, _Method.ArgumentTypes);

            var ctor = ctx.ResolveConstructor(type, new [] { typeof(object), typeof(IntPtr) });
            gen.EmitLoadFunctionPointer(_Method.MethodInfo);
            gen.EmitCreateObject(ctor.ConstructorInfo);
        }
示例#8
0
        private void castNumeric(Context ctx, Type from, Type to)
        {
            var gen = ctx.CurrentMethod.Generator;

            Expression.Emit(ctx, true);

            if (to == typeof (decimal))
            {
                var ctor = ctx.ResolveConstructor(typeof (decimal), new[] { from });
                if (ctor == null)
                {
                    ctor = ctx.ResolveConstructor(typeof(decimal), new[] { typeof(int) });
                    gen.EmitConvert(typeof(int));
                }

                gen.EmitCreateObject(ctor.ConstructorInfo);
            }
            else
            {
                gen.EmitConvert(to);
            }
        }