protected static Expression CallNormal(CodeBlockExpression cbe, params Expression[] ppp) { bool needscontext = NeedsContext(cbe); // true; int pc = ppp.Length; MethodInfo dc = GetDirectCallable(needscontext, pc, cbe.Type); List <Variable> paruninit = new List <Variable>(cbe.Block.Parameters); for (int i = 0; i < ppp.Length; i++) { if (ppp[i].Type == typeof(Uninitialized)) { paruninit[i].SetUnInitialized(); } } if (needscontext) { ppp = ArrayUtils.Insert <Expression>(Ast.CodeContext(), ppp); } var delegatetype = cbe.Type != typeof(Delegate) ? cbe.Type : CallTargets.GetTargetType(needscontext, pc, false); cbe = Ast.CodeBlockReference(cbe.Block, delegatetype); cbe.Block.Bind(); var r = Ast.ComplexCallHelper(cbe, dc, ppp); if (SpanHint.IsValid) { r.SetLoc(SpanHint); } return(r); }
protected static Expression CallVarArgs(CodeBlockExpression cbe, Expression[] ppp) { bool needscontext = NeedsContext(cbe); //true; int pc = cbe.Block.ParameterCount; Expression[] tail = new Expression[ppp.Length - (pc - 1)]; Array.Copy(ppp, ppp.Length - tail.Length, tail, 0, tail.Length); Expression[] nppp = new Expression[pc]; Array.Copy(ppp, nppp, ppp.Length - tail.Length); if (tail.Length > 0) { nppp[nppp.Length - 1] = Ast.ComplexCallHelper(MakeList(tail, true), tail); } else { nppp[nppp.Length - 1] = Ast.Null(); } ppp = nppp; MethodInfo dc = GetDirectCallable(needscontext, pc, cbe.Type); if (needscontext) { ppp = ArrayUtils.Insert <Expression>(Ast.CodeContext(), ppp); } cbe = Ast.CodeBlockReference(cbe.Block, CallTargets.GetTargetType(needscontext, pc, false)); cbe.Block.Bind(); var r = Ast.ComplexCallHelper(cbe, dc, ppp); if (SpanHint.IsValid) { r.SetLoc(SpanHint); } return(r); }
//(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)); }