// Note: This should stay non-public to avoid name conflicts when accessing the // generic overload via GetMethod("NextSite") private static SiteInfo /*!*/ NextSite(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ delegateType) { Type siteType = typeof(SiteStorage <>).MakeGenericType(delegateType); lock (StorageData.SiteLockObj) { int index = (int)siteType.GetField("SiteCount").GetValue(null); siteType.GetField("SiteCount").SetValue(null, index + 1); int arrIndex = index - StorageData.SiteTypes * StorageData.StaticFields; Type storageType = (Type)siteType.GetMethod("SiteStorageType").Invoke(null, new object[] { index }); MSAst.Expression expr; FieldInfo fieldInfo; if (arrIndex < 0) { fieldInfo = storageType.GetField(string.Format("Site{0:000}", index % StorageData.StaticFields)); expr = Ast.Field(null, fieldInfo); } else { fieldInfo = siteType.GetField("Sites"); expr = Ast.ArrayIndex( Ast.Field(null, fieldInfo), Ast.Constant(arrIndex, typeof(int)) ); } return(PublishSite(new SiteInfoLarge(binder, expr, fieldInfo, index, delegateType))); } }
// public for accessibility via GetMethod("NextSite") public static SiteInfo /*!*/ NextSite <T>(DynamicMetaObjectBinder /*!*/ binder) where T : class { lock (StorageData.SiteLockObj) { int index = SiteStorage <T> .SiteCount++; int arrIndex = index - StorageData.SiteTypes * StorageData.StaticFields; Type storageType = SiteStorage <T> .SiteStorageType(index); MSAst.Expression expr; FieldInfo fieldInfo; if (arrIndex < 0) { fieldInfo = storageType.GetField(string.Format("Site{0:000}", index % StorageData.StaticFields)); expr = Ast.Field(null, fieldInfo); } else { fieldInfo = typeof(SiteStorage <T>).GetField("Sites"); expr = Ast.ArrayIndex( Ast.Field(null, fieldInfo), Ast.Constant(arrIndex, typeof(int)) ); } return(PublishSite(new SiteInfo <T>(binder, expr, fieldInfo, index))); } }
public override UncollectableCompilationMode.ConstantInfo GetContext() { lock (StorageData.Contexts) { int index = StorageData.ContextCount++; int arrIndex = index - StorageData.ContextTypes * StorageData.StaticFields; Type storageType = StorageData.ContextStorageType(index); MSAst.Expression expr; FieldInfo fieldInfo; if (arrIndex < 0) { fieldInfo = storageType.GetField(string.Format("Context{0:000}", index % StorageData.StaticFields)); expr = Ast.Field(null, fieldInfo); } else { fieldInfo = typeof(StorageData).GetField("Contexts"); expr = Ast.ArrayIndex( Ast.Field(null, fieldInfo), Ast.Constant(arrIndex, typeof(int)) ); } return(new ConstantInfo(new CodeContextExpression(expr), fieldInfo, index)); } }
public static Expression ByteVectorRef(Expression[] values) { if (values.Length == 2) { return(Ast.Convert(Ast.ArrayIndex(Ast.ConvertHelper(values[0], typeof(byte[])), Ast.ConvertHelper(values[1], typeof(int))), typeof(int))); } UnsafeSyntaxError("$bytevector-ref", "expected 2 arguments", values); return(null); }
public static Expression VectorRef(Expression[] values) { if (values.Length == 2) { if (!typeof(Array).IsAssignableFrom(values[0].Type)) { values[0] = Ast.ConvertHelper(values[0], typeof(object[])); } return(Ast.ArrayIndex(values[0], Ast.ConvertHelper(values[1], typeof(int)))); } UnsafeSyntaxError("$vector-ref", "expected 2 arguments", values); return(null); }
public override MSAst.Expression GetGlobal(MSAst.Expression globalContext, int arrayIndex, PythonVariable variable, PythonGlobal global) { Assert.NotNull(global); return(new PythonGlobalVariableExpression( Ast.ArrayIndex( PythonAst._globalArray, Ast.Constant(arrayIndex) ), variable, global )); }
public override MSAst.Expression /*!*/ Reduce() { Debug.Assert(_start >= 0); Assert.NotNull(_fieldInfo); int index = _offset + _start; int arrIndex = index - FieldCount; if (arrIndex < 0) { return(Ast.Field(null, _fieldInfo)); } else { return(Ast.ArrayIndex( Ast.Field(null, _fieldInfo), Ast.Constant(arrIndex, typeof(int)) )); } }
private static MSA.LambdaExpression /*!*/ CreateLambda(string /*!*/ name, MSA.ParameterExpression /*!*/[] /*!*/ parameters, MSA.Expression /*!*/ body) { Type lambdaType = DynamicSiteHelpers.GetStandardDelegateType(AstFactory.GetSignature(parameters, typeof(object))); if (lambdaType == null) { // to many parameters for Func<> delegate -> use object[]: MSA.ParameterExpression array = Ast.Parameter(typeof(object[]), "#params"); var actualParameters = new MSA.ParameterExpression[] { parameters[0], parameters[1], array }; parameters = ArrayUtils.ShiftLeft(parameters, 2); var bodyWithParamInit = new MSA.Expression[parameters.Length + 1]; for (int i = 0; i < parameters.Length; i++) { bodyWithParamInit[i] = Ast.Assign(parameters[i], Ast.ArrayIndex(array, Ast.Constant(i))); } bodyWithParamInit[parameters.Length] = body; return(Ast.Lambda( RubyMethodInfo.ParamsArrayDelegateType, Ast.Block( new ReadOnlyCollection <MSA.ParameterExpression>(parameters), new ReadOnlyCollection <MSA.Expression>(bodyWithParamInit) ), name, new ReadOnlyCollection <MSA.ParameterExpression>(actualParameters) )); } else { return(Ast.Lambda( lambdaType, body, name, new ReadOnlyCollection <MSA.ParameterExpression>(parameters) )); } }
private void InitializeParameters(List <MSAst.Expression> init, bool needsWrapperMethod, MSAst.Expression[] parameters) { for (int i = 0; i < _parameters.Length; i++) { Parameter p = _parameters[i]; if (needsWrapperMethod) { // if our method signature is object[] we need to first unpack the argument // from the incoming array. init.Add( AssignValue( GetVariableExpression(p.PythonVariable), Ast.ArrayIndex( parameters[1], Ast.Constant(i) ) ) ); } p.Init(init); } }
private static MSA.LambdaExpression /*!*/ CreateLambda(string /*!*/ name, AstParameters /*!*/ parameters, MSA.Expression /*!*/ body) { var result = MethodDispatcher.CreateRubyMethodLambda(body, name, parameters); if (result != null) { return(result); } // to many parameters for Func<> delegate -> use object[]: MSA.ParameterExpression array = Ast.Parameter(typeof(object[]), "#params"); var actualParameters = new AstParameters() { parameters[0], parameters[1], array }; parameters.RemoveAt(0); parameters.RemoveAt(1); var bodyWithParamInit = new AstExpressions(parameters.Count + 1); for (int i = 0; i < parameters.Count; i++) { bodyWithParamInit[i] = Ast.Assign(parameters[i], Ast.ArrayIndex(array, AstUtils.Constant(i))); } bodyWithParamInit[parameters.Count] = body; return(Ast.Lambda <Func <object, Proc, object[], object> >( Ast.Block( parameters, bodyWithParamInit ), name, actualParameters )); }
protected override MSAst.Expression VisitDebugInfo(MSAst.DebugInfoExpression node) { if (!node.IsClear) { MSAst.Expression transformedExpression; // Verify that DebugInfoExpression has valid SymbolDocumentInfo if (node.Document == null) { throw new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, ErrorStrings.DebugInfoWithoutSymbolDocumentInfo, _locationCookie)); } DebugSourceFile sourceFile = _debugContext.GetDebugSourceFile( String.IsNullOrEmpty(node.Document.FileName) ? "<compile>" : node.Document.FileName); // Update the location cookie int locationCookie = _locationCookie++; if (!_transformToGenerator) { MSAst.Expression tracebackCall = null; if (locationCookie == 0) { tracebackCall = Ast.Empty(); } else { tracebackCall = Ast.Call( typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.OnTraceEvent)), _thread, AstUtils.Constant(locationCookie), Ast.Convert(Ast.Constant(null), typeof(Exception)) ); } transformedExpression = Ast.Block( Ast.Assign( _debugMarker, AstUtils.Constant(locationCookie) ), Ast.IfThen( Ast.GreaterThan( Ast.Property(_sourceFilesToVariablesMap[sourceFile], "Mode"), Ast.Constant((int)DebugMode.ExceptionsOnly) ), Ast.IfThen( Ast.OrElse( Ast.Equal( Ast.Property(_sourceFilesToVariablesMap[sourceFile], "Mode"), Ast.Constant((int)DebugMode.FullyEnabled) ), Ast.ArrayIndex( _traceLocations, AstUtils.Constant(locationCookie) ) ), Ast.Block( _pushFrame ?? Ast.Empty(), tracebackCall ) ) ) ); } else { Debug.Assert(_generatorLabelTarget != null); transformedExpression = Ast.Block( AstUtils.YieldReturn( _generatorLabelTarget, _debugYieldValue, locationCookie ) ); // Update the variable scope map if (_currentLocals.Count > 0) { BlockExpression curentBlock = _currentLocals.Peek(); if (!_variableScopeMapCache.TryGetValue(curentBlock, out IList <VariableInfo> scopedVaribles)) { scopedVaribles = new List <VariableInfo>(); BlockExpression[] blocks = _currentLocals.ToArray(); for (int i = blocks.Length - 1; i >= 0; i--) { foreach (var variable in blocks[i].Variables) { scopedVaribles.Add(_localsToVarInfos[variable]); } } _variableScopeMapCache.Add(curentBlock, scopedVaribles); } _variableScopeMap.Add(locationCookie, scopedVaribles); } DebugSourceSpan span = new DebugSourceSpan( sourceFile, node.StartLine, node.StartColumn, node.EndLine, node.EndColumn); // Update the location-span map _markerLocationMap.Add(locationCookie, span); } return(transformedExpression); } return(Ast.Empty()); }
// (clr-call type member obj arg1 ... ) public override Expression Generate(object args, CodeBlock cb) { Type t = null; string type = null; bool inferred = false; object rtype = Builtins.First(args); ExtractTypeInfo(rtype, out t, out type, out inferred); string member = null; var marg = Builtins.Second(args); object memobj = null; Type[] argtypes = null; Type[] gentypes = null; if (marg is SymbolId) { var mem = Builtins.SymbolValue(marg); if (mem is Cons) { ExtractMethodInfo(mem as Cons, out member, ref argtypes, ref gentypes); } else { ClrSyntaxError("clr-call", "type member not supported", mem); } } else { memobj = Builtins.Second(marg); member = memobj is SymbolId?SymbolTable.IdToString((SymbolId)memobj) : ""; if (memobj is string) { string mems = memobj as string; int bi = mems.IndexOf('('); if (bi < 0) { member = mems; } else { member = mems.Substring(0, bi); } } else if (memobj is Cons) { ExtractMethodInfo(memobj as Cons, out member, ref argtypes, ref gentypes); } } Expression instance = GetAst(Builtins.Third(args), cb); CallType ct = CallType.ImplicitInstance; if (instance is ConstantExpression && ((ConstantExpression)instance).Value == null) { ct = CallType.None; if (inferred) { ClrSyntaxError("clr-call", "type inference not possible on static member", member); } } else if (inferred) { if (instance is UnaryExpression && instance.Type == typeof(object)) { var ue = (UnaryExpression)instance; instance = ue.Operand; } t = instance.Type; } else { instance = ConvertToHelper(t, instance); } type = t.Name; Expression[] arguments = GetAstListNoCast(Cdddr(args) as Cons, cb); if (member == "get_Item") { if (Attribute.IsDefined(t, typeof(DefaultMemberAttribute))) { var dma = Attribute.GetCustomAttribute(t, typeof(DefaultMemberAttribute)) as DefaultMemberAttribute; member = "get_" + dma.MemberName; } else if (t.IsArray) { var index = arguments[0]; return(Ast.ArrayIndex(instance, Ast.ConvertHelper(index, typeof(int)))); } } else if (member == "set_Item") { if (Attribute.IsDefined(t, typeof(DefaultMemberAttribute))) { var dma = Attribute.GetCustomAttribute(t, typeof(DefaultMemberAttribute)) as DefaultMemberAttribute; member = "set_" + dma.MemberName; } else if (t.IsArray) { var index = arguments[0]; var v = arguments[1]; return(Ast.Comma(Ast.AssignArrayIndex(instance, Ast.ConvertHelper(index, typeof(int)), v), Ast.ReadField(null, Unspecified))); } } List <MethodBase> candidates = new List <MethodBase>(); BindingFlags bf = BindingFlags.Public | (ct == CallType.None ? BindingFlags.Static : BindingFlags.Instance) | BindingFlags.FlattenHierarchy; foreach (MethodInfo mi in t.GetMember(member, MemberTypes.Method, bf)) { if (PAL.ExcludeParamtypes(mi)) { continue; } if (mi.ContainsGenericParameters) { if (gentypes != null && mi.GetGenericArguments().Length == gentypes.Length) { candidates.Add(mi.MakeGenericMethod(gentypes)); continue; } } candidates.Add(mi); } Type[] types = new Type[arguments.Length]; for (int i = 0; i < types.Length; i++) { types[i] = arguments[i].Type; } if (memobj is string) { string mems = memobj as string; int bi = mems.IndexOf('('); if (bi < 0) { // do notthig } else { string[] typeargs = mems.Substring(bi + 1).TrimEnd(')').Split(','); for (int i = 0; i < types.Length; i++) { if (typeargs[i].Length > 0) { types[i] = ScanForType(typeargs[i]); } } } } else if (argtypes != null) { for (int i = 0; i < types.Length; i++) { types[i] = argtypes[i]; } } if (ct == CallType.ImplicitInstance) { types = ArrayUtils.Insert(t, types); } MethodBinder mb = MethodBinder.MakeBinder(Binder, member, candidates, BinderType.Normal); MethodCandidate mc = mb.MakeBindingTarget(ct, types); if (mc == null) { types = new Type[arguments.Length]; for (int i = 0; i < types.Length; i++) { types[i] = typeof(object); } if (ct == CallType.ImplicitInstance) { types = ArrayUtils.Insert(t, types); } mc = mb.MakeBindingTarget(ct, types); } if (mc != null) { MethodInfo meth = (MethodInfo)mc.Target.Method; // do implicit cast ParameterInfo[] pars = meth.GetParameters(); for (int i = 0; i < arguments.Length; i++) { Type tt = pars[i].ParameterType; arguments[i] = ConvertToHelper(tt, arguments[i]); } Expression r = null; // o god... if (ct == CallType.ImplicitInstance) { r = Ast.ComplexCallHelper(instance, (MethodInfo)mc.Target.Method, arguments); } else { r = Ast.ComplexCallHelper((MethodInfo)mc.Target.Method, arguments); } return(ConvertFromHelper(meth.ReturnType, r)); } ClrSyntaxError("clr-call", "member could not be resolved on type: " + type, args, member); return(null); }
protected internal static Expression GetAst(object args, CodeBlock cb, bool istailposition) { if (args is Annotation) { args = ((Annotation)args).stripped; } Cons c = args as Cons; if (c != null) { if (c.car is SymbolId) { SymbolId f = (SymbolId)c.car; Variable var = cb.Lookup(f); if (var != null && !assigns.ContainsKey(f)) { var = null; } object m; #if OPTIMIZATIONS #if !BLAH CodeBlockExpression cbe; //// needs to do the same for overloads... if (SimpleGenerator.libraryglobals.TryGetValue(f, out cbe)) { Expression[] ppp = GetAstListNoCast(c.cdr as Cons, cb); if (cbe.Block.ParameterCount < 9 && cbe.Block.ParameterCount == ppp.Length) { //inline here? we could for simple bodies, but we need to copy the entire structure if (!(cbe.Block.HasEnvironment || cbe.Block.IsClosure)) { if (cbe.Block.Body is ReturnStatement) { ReturnStatement rs = (ReturnStatement)cbe.Block.Body; if (!ScriptDomainManager.Options.DebugMode && !ScriptDomainManager.Options.LightweightDebugging && !cb.IsGlobal && IsSimpleExpression(rs.Expression)) { return(InlineCall(cb, Ast.CodeBlockExpression(RewriteBody(cbe.Block), false, cbe.IsStronglyTyped), ppp)); } } } if (cbe.Block != cb.Parent && cbe.Block != cb) // do TCE later { return(CallNormal(cbe, ppp)); } } } // varargs if (SimpleGenerator.libraryglobalsX.TryGetValue(f, out cbe)) { Expression[] ppp = GetAstListNoCast(c.cdr as Cons, cb); if (cbe.Block.ParameterCount < 9 && cbe.Block.ParameterCount - 1 <= ppp.Length) { //inline here? return(CallVarArgs(cbe, ppp)); } } // overloads CodeBlockDescriptor[] cbd; if (SimpleGenerator.libraryglobalsN.TryGetValue(f, out cbd)) { Expression[] ppp = GetAstListNoCast(c.cdr as Cons, cb); foreach (CodeBlockDescriptor d in cbd) { if (d.codeblock.Block.ParameterCount < 9) { if (ppp.Length == d.arity || (d.varargs && ppp.Length > d.arity)) { if (d.varargs) { //inline here? return(CallVarArgs(d.codeblock, ppp)); } else { //inline here? //if (d.codeblock.Block != cb.Parent && d.codeblock.Block != cb) // do TCE later, not yet { return(CallNormal(d.codeblock, ppp)); } } } } } } #endif //if (!ScriptDomainManager.Options.DebugMode) { if (f == SymbolTable.StringToId("call-with-values")) { Expression[] ppp = GetAstListNoCast(c.cdr as Cons, cb); if (ppp.Length == 2 && ppp[1] is MethodCallExpression) { MethodCallExpression consumer = ppp[1] as MethodCallExpression; if (ppp[0] is MethodCallExpression) { MethodCallExpression producer = ppp[0] as MethodCallExpression; if (consumer.Method == Closure_Make && producer.Method == Closure_Make) { CodeBlockExpression ccbe = consumer.Arguments[0] as CodeBlockExpression; CodeBlockExpression pcbe = producer.Arguments[0] as CodeBlockExpression; pcbe.Block.Bind(); ccbe.Block.Bind(); if (ccbe.Block.ParameterCount == 0) { return(InlineCall(cb, ccbe)); } else if (ccbe.Block.ParameterCount == 1) { return(InlineCall(cb, ccbe, Ast.SimpleCallHelper(typeof(Helpers).GetMethod("UnwrapValue"), InlineCall(cb, pcbe)))); } else { Variable values = cb.CreateTemporaryVariable((SymbolId)Builtins.GenSym("values"), typeof(object[])); Expression valuesarr = Ast.Read(values); Expression[] pppp = new Expression[ccbe.Block.ParameterCount]; for (int i = 0; i < pppp.Length; i++) { pppp[i] = Ast.ArrayIndex(valuesarr, Ast.Constant(i)); } return(Ast.Comma( Ast.Void( Ast.Write( values, Ast.ComplexCallHelper( Ast.SimpleCallHelper(typeof(Helpers).GetMethod("WrapValue"), InlineCall(cb, pcbe)), typeof(MultipleValues).GetMethod("ToArray", new Type[] { typeof(int) }), Ast.Constant(pppp.Length)))), InlineCall(cb, ccbe, pppp))); } } } if (consumer.Method == Closure_Make) { CodeBlockExpression ccbe = consumer.Arguments[0] as CodeBlockExpression; ccbe.Block.Bind(); Expression producer = ppp[0]; Expression exx = Ast.ConvertHelper(producer, typeof(Callable)); MethodInfo callx = GetCallable(0); if (ccbe.Block.ParameterCount == 0) { return(InlineCall(cb, ccbe)); } else if (ccbe.Block.ParameterCount == 1) { return(InlineCall(cb, ccbe, Ast.SimpleCallHelper(typeof(Helpers).GetMethod("UnwrapValue"), Ast.Call(exx, callx)))); } else { Variable values = cb.CreateTemporaryVariable((SymbolId)Builtins.GenSym("values"), typeof(object[])); Expression valuesarr = Ast.Read(values); Expression[] pppp = new Expression[ccbe.Block.ParameterCount]; for (int i = 0; i < pppp.Length; i++) { pppp[i] = Ast.ArrayIndex(valuesarr, Ast.Constant(i)); } return(Ast.Comma( Ast.Void( Ast.Write( values, Ast.ComplexCallHelper( Ast.SimpleCallHelper(typeof(Helpers).GetMethod("WrapValue"), Ast.Call(exx, callx)), typeof(MultipleValues).GetMethod("ToArray", new Type[] { typeof(int) }), Ast.Constant(pppp.Length)))), InlineCall(cb, ccbe, pppp))); } } } else { ; } } } #endif // this can be enabled once builtins are auto CPS'd. // ok I tried, but there are issues still, not sure what #if OPTIMIZATIONS // check for inline emitter InlineEmitter ie; if (TryGetInlineEmitter(f, out ie)) { Expression result = ie(GetAstList(c.cdr as Cons, cb)); // if null is returned, the method cannot be inlined if (result != null) { if (spanhint.IsValid) { result.SetLoc(spanhint); } return(result); } } #endif if (Context.Scope.TryLookupName(f, out m)) { if (var == null) { IGenerator gh = m as IGenerator; if (gh != null) { return(gh.Generate(c.cdr, cb)); } BuiltinMethod bf = m as BuiltinMethod; if (bf != null) { MethodBinder mb = bf.Binder; Expression[] pars = Array.ConvertAll(GetAstList(c.cdr as Cons, cb), e => Unwrap(e)); if (bf.AllowConstantFold && !ScriptDomainManager.Options.DebugMode) { bool constant = Array.TrueForAll(pars, e => e is ConstantExpression && e.Type != typeof(BigInteger)); if (constant) { object[] cargs = Array.ConvertAll(pars, e => GetRuntimeConstant((ConstantExpression)e)); CallTarget0 disp = delegate { return(bf.Call(cargs)); }; CallTarget1 handler = delegate(object e) { throw new CompileTimeEvaluationException(); }; try { object result = Runtime.R6RS.Exceptions.WithExceptionHandler( Closure.Create(handler), Closure.Create(disp)); var rrrr = GetCons(result, cb); if (spanhint.IsValid) { rrrr.SetLoc(spanhint); } return(rrrr); } catch (CompileTimeEvaluationException) { } } } Type[] types = GetExpressionTypes(pars); MethodCandidate mc = mb.MakeBindingTarget(CallType.None, types); if (mc != null) { if (mc.Target.NeedsContext) { pars = ArrayUtils.Insert <Expression>(Ast.CodeContext(), pars); } MethodBase meth = mc.Target.Method; var rrrr = Ast.ComplexCallHelper(meth as MethodInfo, pars); if (spanhint.IsValid) { rrrr.SetLoc(spanhint); } return(rrrr); } } Closure clos = m as Closure; if (clos != null && !SetGenerator.IsAssigned(f)) { // no provision for varargs MethodInfo[] mis = clos.Targets; if (mis.Length > 0) { MethodBinder mb = MethodBinder.MakeBinder(binder, SymbolTable.IdToString(f), mis, BinderType.Normal); Expression[] pars = Array.ConvertAll(GetAstList(c.cdr as Cons, cb), e => Unwrap(e)); if (clos.AllowConstantFold && !ScriptDomainManager.Options.DebugMode) { bool constant = Array.TrueForAll(pars, e => e is ConstantExpression && e.Type != typeof(BigInteger)); if (constant) { object[] cargs = Array.ConvertAll(pars, e => GetRuntimeConstant((ConstantExpression)e)); CallTarget0 disp = delegate { var rrrr = clos.Call(cargs); return(rrrr); }; CallTarget1 handler = delegate(object e) { throw new CompileTimeEvaluationException(); }; try { object result = Runtime.R6RS.Exceptions.WithExceptionHandler( Closure.Create(handler), Closure.Create(disp)); var rrrr = GetCons(result, cb); if (spanhint.IsValid) { rrrr.SetLoc(spanhint); } return(rrrr); } catch (CompileTimeEvaluationException) { } } } // exclude transient members if needed if (!AllowTransientBinding) { mis = Array.FindAll(mis, x => !IsTransient(x.Module)); } if (mis.Length > 0) { Type[] types = GetExpressionTypes(pars); MethodCandidate mc = mb.MakeBindingTarget(CallType.None, types); if (mc != null) { if (mc.Target.NeedsContext) { pars = ArrayUtils.Insert <Expression>(Ast.CodeContext(), pars); } MethodBase meth = mc.Target.Method; var rrrr = Ast.ComplexCallHelper(meth as MethodInfo, pars); if (spanhint.IsValid) { rrrr.SetLoc(spanhint); } return(rrrr); } } } // check for overload thing } } } } Expression ex = Unwrap(GetAst(c.car, cb)); // a 'let' if (ex is MethodCallExpression) { var ppp = GetAstList(c.cdr as Cons, cb); MethodCallExpression mcexpr = (MethodCallExpression)ex; if (mcexpr.Method == Closure_Make) { CodeBlockExpression cbe = mcexpr.Arguments[0] as CodeBlockExpression; if (ppp.Length < 9 && cbe.Block.ParameterCount == ppp.Length) { return(InlineCall(cb, cbe, istailposition, ppp)); } } // cater for varargs more efficiently, this does not seem to hit, probably needed somewhere else if (mcexpr.Method == Closure_MakeVarArgsX) { CodeBlockExpression cbe = mcexpr.Arguments[0] as CodeBlockExpression; if (ppp.Length < 9 && cbe.Block.ParameterCount <= ppp.Length) { return(CallVarArgs(cbe, ppp)); } } } if (ex is NewExpression && typeof(ITypedCallable).IsAssignableFrom(ex.Type)) { NewExpression mcexpr = ex as NewExpression; CodeBlockExpression cbe = mcexpr.Arguments[0] as CodeBlockExpression; if (cbe == null && mcexpr.Arguments[0].Type == typeof(CodeContext) && mcexpr.Arguments[0] is ConstantExpression) // implies null { cbe = mcexpr.Arguments[1] as CodeBlockExpression; } if (cbe != null) { var ppp = GetAstListNoCast(c.cdr as Cons, cb); if (ppp.Length < 9 && cbe.Block.ParameterCount == ppp.Length) { return(InlineCall(cb, cbe, istailposition, ppp)); } } } if (ex is ConstantExpression) { Builtins.SyntaxError(SymbolTable.StringToObject("generator"), "expecting a procedure", c.car, c); } Expression r = null; if (ex.Type.Name.Contains("TypedClosure")) { Expression[] pp = GetAstListNoCast(c.cdr as Cons, cb); var m = ex.Type.GetMethod("Invoke"); r = Ast.SimpleCallHelper(ex, m, pp); } else { Expression[] pp = GetAstList(c.cdr as Cons, cb); if (ex.Type != typeof(Callable)) { ex = Ast.ConvertHelper(ex, typeof(Callable)); } MethodInfo call = GetCallable(pp.Length); r = pp.Length > 8 ? Ast.Call(ex, call, Ast.NewArray(typeof(object[]), pp)) : Ast.Call(ex, call, pp); } if (spanhint.IsValid) { r.SetLoc(spanhint); } return(r); } object[] v = args as object[]; if (v != null) { return(GetConsVector(v, cb)); } else if (args is byte[]) { Expression[] ba = Array.ConvertAll(args as byte[], b => Ast.Constant(b)); return(Ast.NewArray(typeof(byte[]), ba)); } else { if (args is SymbolId) { SymbolId sym = (SymbolId)args; if (sym == SymbolTable.StringToId("uninitialized")) { return(Ast.ReadField(null, typeof(Uninitialized), "Instance")); } else { return(Read(sym, cb, typeof(object))); } } if (args == Builtins.Unspecified) { return(Ast.ReadField(null, Unspecified)); } if (args is Fraction) { Fraction f = (Fraction)args; return(Ast.Constant(new FractionConstant(f))); } if (args is ComplexFraction) { ComplexFraction f = (ComplexFraction)args; return(Ast.Constant(new ComplexFractionConstant(f))); } if (args != null && args.GetType().Name == "stx") { args = new SerializedConstant(args); } return(Ast.Constant(args)); } }
private bool MakeDefaultMemberRule(Operators oper) { if (_types[0].IsArray) { if (Binder.CanConvertFrom(_types[1], typeof(int), NarrowingLevel.All)) { if (oper == Operators.GetItem) { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.ArrayIndex( Param0, ConvertIfNeeded(Param1, typeof(int)) ) )); } else { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.AssignArrayIndex( Param0, ConvertIfNeeded(Param1, typeof(int)), ConvertIfNeeded(Param2, _types[0].GetElementType()) ) )); } return(true); } } MethodInfo[] defaults = GetMethodsFromDefaults(_types[0].GetDefaultMembers(), oper); if (defaults.Length != 0) { MethodBinder binder = MethodBinder.MakeBinder(Binder, oper == Operators.GetItem ? "get_Item" : "set_Item", defaults, BinderType.Normal); MethodCandidate cand = binder.MakeBindingTarget(CallType.ImplicitInstance, _types); if (cand != null) { if (oper == Operators.GetItem) { _rule.SetTarget(_rule.MakeReturn(Binder, cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types))); } else { _rule.SetTarget(_rule.MakeReturn(Binder, Ast.Comma(0, _rule.Parameters[2], cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types) ) )); } } else { _rule.SetTarget(Binder.MakeInvalidParametersError(binder, Action, CallType.None, defaults, _rule, _args)); } return(true); } return(false); }