예제 #1
0
        //(import (ironscheme clr))
        //(define f (ffi-callout int32 (void* uint16)))
        public override Expression Generate(object args, CodeBlock cb)
        {
            Cons c          = args as Cons;
            Type returntype = GetFFIType(Unquote(c.car));

            c = c.cdr as Cons;

            List <Type> paramtypes = new List <Type>();

            while (c != null)
            {
                paramtypes.Add(GetFFIType(Unquote(c.car)));
                c = c.cdr as Cons;
            }

            CodeBlock outer = Ast.CodeBlock("outer");

            outer.Parent = cb;

            Variable ptr = Variable.Parameter(outer, SymbolTable.StringToId("ptr"), typeof(object));

            outer.AddParameter(ptr);

            CodeBlock inner = GenerateInvoke("ffi-callout",
                                             a => MakePointerCall(ptr, returntype, paramtypes, a),
                                             returntype,
                                             paramtypes,
                                             outer);

            outer.Body = Ast.Return(MakeClosure(inner, false));

            return(MakeClosure(outer, false));
        }
예제 #2
0
        static Variable CreateParameter(SymbolId sname, CodeBlock cb, Type type)
        {
            Variable v = Variable.Parameter(cb, sname, type);

            cb.AddParameter(v);
            return(v);
        }
예제 #3
0
        protected static CodeBlock GenerateCallback(string proc, PInvokeHandler pinvokecall, Type returntype, List <Type> paramtypes, CodeBlock cb)
        {
            CodeBlock call = Ast.CodeBlock(proc, returntype);

            call.Parent = cb;

            int count = 0;

            List <Variable> pars = new List <Variable>();

            foreach (Type t in paramtypes)
            {
                var      name = SymbolTable.StringToId("arg" + count++);
                Variable var  = Variable.Parameter(call, name, t);
                call.AddParameter(var);

                pars.Add(var);
            }

            Variable ret = returntype == typeof(void) ? null : Create(SymbolTable.StringToId("ret"), call, typeof(object));

            List <Statement> stmts = new List <Statement>();

            Expression[] arguments = new Expression[pars.Count];

            for (int i = 0; i < pars.Count; i++)
            {
                arguments[i] = MakeConvertFrom(Ast.Read(pars[i]), paramtypes[i]);
            }

            var fficall = pinvokecall(arguments);

            if (ret == null)
            {
                stmts.Add(Ast.Statement(fficall));
            }
            else
            {
                stmts.Add(Ast.Write(ret, fficall));
                stmts.Add(Ast.Return(MakeConvertTo(Ast.Read(ret), returntype)));
            }

            call.Body = Ast.Block(stmts);

            return(call);
        }
예제 #4
0
        //(import (ironscheme clr))
        //(define f (ffi-callback int32 (void* uint16)))
        public override Expression Generate(object args, CodeBlock cb)
        {
            Cons c          = args as Cons;
            Type returntype = GetFFIType(Unquote(c.car));

            c = c.cdr as Cons;

            List <Type> paramtypes = new List <Type>();

            while (c != null)
            {
                paramtypes.Add(GetFFIType(Unquote(c.car)));
                c = c.cdr as Cons;
            }

            CodeBlock outer = Ast.CodeBlock("outer");

            outer.Parent = cb;

            Variable proc = Variable.Parameter(outer, SymbolTable.StringToId("proc"), typeof(object));

            outer.AddParameter(proc);

            Type sig = MakeDelegateType(returntype, paramtypes);

            CodeBlock inner = GenerateCallback("ffi-callback",
                                               a => MakeCallBack(proc, a),
                                               returntype,
                                               paramtypes,
                                               outer);

            var del = Ast.CodeBlockReference(inner, sig);

            outer.Body = Ast.Block(
                Ast.Statement(MakeClosure(inner, false)),
                Ast.Return(Ast.Call(FFIFunctionPointer, Ast.Constant(sig), del, Ast.CodeContext())));

            return(MakeClosure(outer, false));
        }
예제 #5
0
 static Variable CreateParameter(SymbolId sname, CodeBlock cb, Type type)
 {
     Variable v = Variable.Parameter(cb, sname, type);
       cb.AddParameter(v);
       return v;
 }