public override Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val) { Expression target = _target.GenCode(RHC.Expression, objx, context); Expression valExpr = val.GenCode(RHC.Expression, objx, context); Expression call; if (_targetType != null && _tinfo != null) { Expression convTarget = Expression.Convert(target, _targetType); Expression access = GenAccess(rhc, objx, convTarget); Expression unboxValExpr = HostExpr.GenUnboxArg(valExpr, FieldType); //call = Expression.Assign(access, Expression.Convert(valExpr, access.Type)); call = Expression.Assign(access, unboxValExpr); } else { // TODO: Convert to a dynamic call site call = Expression.Call( Compiler.Method_Reflector_SetInstanceFieldOrProperty, target, Expression.Constant(_fieldName), Compiler.MaybeBox(valExpr)); } call = Compiler.MaybeAddDebugInfo(call, _spanMap, context.IsDebuggable); return(call); }
public override Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val) { Expression access = GenCodeUnboxed(RHC.Expression, objx, context); Expression valExpr = val.GenCode(RHC.Expression, objx, context); Expression unboxValExpr = HostExpr.GenUnboxArg(valExpr, FieldType); Expression assign = Expression.Assign(access, unboxValExpr); assign = Compiler.MaybeAddDebugInfo(assign, _spanMap, context.IsDebuggable); return(assign); }
public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context) { LabelTarget loopLabel = (LabelTarget)Compiler.LoopLabelVar.deref(); if (loopLabel == null) { throw new InvalidOperationException("Recur not in proper context."); } int argCount = _args.count(); List <ParameterExpression> tempVars = new List <ParameterExpression>(argCount); List <Expression> tempAssigns = new List <Expression>(argCount); List <Expression> finalAssigns = new List <Expression>(argCount); // Evaluate all the init forms into local variables. for (int i = 0; i < _loopLocals.count(); i++) { LocalBinding lb = (LocalBinding)_loopLocals.nth(i); Expr arg = (Expr)_args.nth(i); ParameterExpression tempVar; Expression valExpr; Type primt = lb.PrimitiveType; if (primt != null) { tempVar = Expression.Parameter(primt, "__local__" + i); MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr; Type pt = Compiler.MaybePrimitiveType(arg); if (pt == primt) { valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context); // do nothing } else if (primt == typeof(long) && pt == typeof(int)) { valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context); valExpr = Expression.Convert(valExpr, primt); } else if (primt == typeof(double) && pt == typeof(float)) { valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context); valExpr = Expression.Convert(valExpr, primt); } else if (primt == typeof(int) && pt == typeof(long)) { valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context); valExpr = Expression.Convert(valExpr, primt); } else if (primt == typeof(float) && pt == typeof(double)) { valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context); valExpr = Expression.Convert(valExpr, primt); } else { //if (true) //RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) //RT.errPrintWriter().WriteLine throw new ArgumentException(String.Format( "{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}", _source, _spanMap != null ? (int)_spanMap.valAt(RT.StartLineKey, 0) : 0, lb.Name, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name)); //valExpr = arg.GenCode(RHC.Expression, objx, context); // valExpr = Expression.Convert(valExpr, primt); } } else { tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i); valExpr = arg.GenCode(RHC.Expression, objx, context); } //ParameterExpression tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i); //Expression valExpr = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context); tempVars.Add(tempVar); //if (tempVar.Type == typeof(Object)) // tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr))); //else // tempAssigns.Add(Expression.Assign(tempVar, Expression.Convert(valExpr, tempVar.Type))); if (valExpr.Type.IsPrimitive && !tempVar.Type.IsPrimitive) { tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr))); } else if (!valExpr.Type.IsPrimitive && tempVar.Type.IsPrimitive) { tempAssigns.Add(Expression.Assign(tempVar, HostExpr.GenUnboxArg(valExpr, tempVar.Type))); } else { tempAssigns.Add(Expression.Assign(tempVar, valExpr)); } finalAssigns.Add(Expression.Assign(lb.ParamExpression, tempVar)); } List <Expression> exprs = tempAssigns; exprs.AddRange(finalAssigns); exprs.Add(Expression.Goto(loopLabel)); // need to do this to get a return value in the type inferencing -- else can't use this in a then or else clause. exprs.Add(Expression.Constant(null)); return(Expression.Block(tempVars, exprs)); }
MethodBuilder GenerateStaticMethod(ObjExpr objx, GenContext context) { string methodName = StaticMethodName; TypeBuilder tb = objx.TypeBuilder; List <ParameterExpression> parms = new List <ParameterExpression>(_argLocals.count() + 1); List <Type> parmTypes = new List <Type>(_argLocals.count() + 1); ParameterExpression thisParm = Expression.Parameter(objx.BaseType, "this"); if (_thisBinding != null) { _thisBinding.ParamExpression = thisParm; _thisBinding.Tag = Symbol.intern(null, objx.BaseType.FullName); } objx.ThisParam = thisParm; parms.Add(thisParm); parmTypes.Add(objx.BaseType); try { LabelTarget loopLabel = Expression.Label("top"); Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this)); Type[] argTypes = StaticMethodArgTypes; for (int i = 0; i < _argLocals.count(); i++) { LocalBinding lb = (LocalBinding)_argLocals.nth(i); ParameterExpression parm = Expression.Parameter(argTypes[i], lb.Name); lb.ParamExpression = parm; parms.Add(parm); parmTypes.Add(argTypes[i]); } Expression body = Expression.Block( //maybeLoadVarsExpr, Expression.Label(loopLabel), GenBodyCode(StaticReturnType, objx, context)); //Expression convBody = Compiler.MaybeConvert(body, ReturnType); Expression convBody = HostExpr.GenUnboxArg(body, StaticReturnType); LambdaExpression lambda = Expression.Lambda(convBody, parms); // JVM: Clears locals here. // TODO: Cache all the CreateObjectTypeArray values MethodBuilder mb = tb.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, StaticReturnType, parmTypes.ToArray()); //Console.Write("StMd: {0} {1}(", ReturnType.Name, methodName); //foreach (Type t in parmTypes) // Console.Write("{0}, ", t.Name); //Console.WriteLine(")"); lambda.CompileToMethod(mb, context.IsDebuggable); _staticMethodBuilder = mb; return(mb); } finally { Var.popThreadBindings(); } }
protected Expression GenDlrForMethod(ObjExpr objx, GenContext context) { if (_method.DeclaringType == (Type)Compiler.CompileStubOrigClassVar.deref()) { _method = FindEquivalentMethod(_method, objx.BaseType); } int argCount = _args.Count; IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (IsStaticCall ? 0 : 1)); if (!IsStaticCall) { argsPlus.Add(new DynamicMetaObject(Expression.Convert(GenTargetExpression(objx, context), _method.DeclaringType), BindingRestrictions.Empty)); } List <int> refPositions = new List <int>(); ParameterInfo[] methodParms = _method.GetParameters(); for (int i = 0; i < argCount; i++) { HostArg ha = _args[i]; Expr e = ha.ArgExpr; Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object); //Type t; switch (ha.ParamType) { case HostArg.ParameterType.ByRef: refPositions.Add(i); argsPlus.Add(new DynamicMetaObject(HostExpr.GenUnboxArg(GenTypedArg(objx, context, argType, e), methodParms[i].ParameterType.GetElementType()), BindingRestrictions.Empty)); break; case HostArg.ParameterType.Standard: Type ptype = methodParms[i].ParameterType; if (ptype.IsGenericParameter) { ptype = argType; } Expression typedArg = GenTypedArg(objx, context, ptype, e); argsPlus.Add(new DynamicMetaObject(typedArg, BindingRestrictions.Empty)); break; default: throw Util.UnreachableCode(); } } // TODO: get rid of use of Default OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory; DefaultOverloadResolver res = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), IsStaticCall ? CallTypes.None : CallTypes.ImplicitInstance); List <MethodBase> methods = new List <MethodBase>(); methods.Add(_method); BindingTarget bt = res.ResolveOverload(_methodName, methods, NarrowingLevel.None, NarrowingLevel.All); if (!bt.Success) { throw new ArgumentException("Conflict in argument matching. -- Internal error."); } Expression call = bt.MakeExpression(); if (refPositions.Count > 0) { ParameterExpression resultParm = Expression.Parameter(typeof(Object[])); List <Expression> stmts = new List <Expression>(refPositions.Count + 2); stmts.Add(Expression.Assign(resultParm, call)); // TODO: Fold this into the loop above foreach (int i in refPositions) { HostArg ha = _args[i]; Expr e = ha.ArgExpr; Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object); stmts.Add(Expression.Assign(_args[i].LocalBinding.ParamExpression, Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(i + 1)), argType))); } Type returnType = HasClrType ? ClrType : typeof(object); stmts.Add(Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(0)), returnType)); call = Expression.Block(new ParameterExpression[] { resultParm }, stmts); } call = _arithmeticRewriter.Visit(call); return(call); }