//(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)); }
static Variable CreateParameter(SymbolId sname, CodeBlock cb, Type type) { Variable v = Variable.Parameter(cb, sname, type); cb.AddParameter(v); return(v); }
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); }
//(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)); }
static Variable CreateParameter(SymbolId sname, CodeBlock cb, Type type) { Variable v = Variable.Parameter(cb, sname, type); cb.AddParameter(v); return v; }