protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { // Need to add the type of the base method of the virtual call, so // the virtual method table is generated correctly this.types.Add(e.CallMethod.DeclaringType); return(base.VisitJsVirtualCall(e)); }
protected override ICode VisitCall(ExprCall e) { var expr = this.HandleCall(e, (obj, args) => new ExprCall(e.Ctx, e.CallMethod, obj, args, e.IsVirtualCall, e.ConstrainedType, e.Type)); var res = JsResolver.ResolveCallSite(expr); if (res != null) { return this.Visit(res); } if (expr.ConstrainedType != null) { if (expr.ConstrainedType.IsValueType) { // Map constrained virtual call to a method on a value-type, to a non-virtual call. // This is important as it prevents having to box the value-type, which is expensive var impl = expr.ConstrainedType.EnumResolvedMethods().FirstOrDefault(x => x.MatchMethodOnly(expr.CallMethod)); if (impl != null) { var constrainedCall = new ExprCall(expr.Ctx, impl, expr.Obj, expr.Args, false, null, expr.Type); return constrainedCall; } else { throw new Exception(); } } } if (expr.IsVirtualCall) { var ctx = expr.Ctx; var objIsVar = expr.Obj.IsVar(); var temp = objIsVar ? null : new ExprVarLocal(ctx, expr.Obj.Type); var getTypeObj = objIsVar ? expr.Obj : new ExprAssignment(ctx, temp, expr.Obj); var getType = new ExprCall(ctx, typeof(object).GetMethod("GetType"), getTypeObj); var eJsVCall = new ExprJsVirtualCall(ctx, expr.CallMethod, getType, temp ?? expr.Obj, expr.Args); return eJsVCall; } return expr; }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { var ctx = e.Ctx; var byRefs = new List <Tuple <Expr, Expr> >(); var args = e.CallMethod.Parameters.Zip(e.Args, (p, a) => new { p, a }) .Select(x => { if (x.p.ParameterType.IsByReference) { var wrapper = ctx.Local(ctx.IntPtr); byRefs.Add(Tuple.Create(x.a, (Expr)wrapper)); return(wrapper); } else { return(x.a); } }) .ToArray(); if (!args.SequenceEqual(e.Args)) { var call = new ExprJsVirtualCall(ctx, e.CallMethod, e.RuntimeType, e.ObjRef, args); var resultTemp = ctx.Local(e.Type); return(new ExprJsByRefWrapper(e.Ctx, call, resultTemp, byRefs)); } return(base.VisitJsVirtualCall(e)); }
protected virtual ICode VisitJsVirtualCall(ExprJsVirtualCall e) { this.ThrowOnNoOverride(); var runtimeType = (Expr)this.Visit(e.RuntimeType); var objRef = (Expr)this.Visit(e.ObjRef); var args = this.HandleList(e.Args, x => (Expr)this.Visit(x)); if (runtimeType != e.RuntimeType || objRef != e.ObjRef || args != null) { return(new ExprJsVirtualCall(e.Ctx, e.CallMethod, runtimeType, objRef, args ?? e.Args)); } else { return(e); } }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { var ctx = e.Ctx; var byRefs = new List<Tuple<Expr,Expr>>(); var args = e.CallMethod.Parameters.Zip(e.Args, (p, a)=>new {p,a}) .Select(x=>{ if (x.p.ParameterType.IsByReference) { var wrapper = ctx.Local(ctx.IntPtr); byRefs.Add(Tuple.Create(x.a, (Expr)wrapper)); return wrapper; }else{ return x.a; } }) .ToArray(); if (!args.SequenceEqual(e.Args)) { var call = new ExprJsVirtualCall(ctx, e.CallMethod, e.RuntimeType, e.ObjRef, args); var resultTemp = ctx.Local(e.Type); return new ExprJsByRefWrapper(e.Ctx, call, resultTemp, byRefs); } return base.VisitJsVirtualCall(e); }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { var isIFaceCall = e.CallMethod.DeclaringType.Resolve().IsInterface; if (isIFaceCall) { var iTableIndex = this.resolver.InterfaceCallIndices[e.CallMethod]; var iFaceName = this.resolver.InterfaceNames[e.CallMethod.DeclaringType]; this.Visit(e.RuntimeType); this.js.AppendFormat(".{0}[{1}]", iFaceName, iTableIndex); this.CallAppendArgs(e); } else { var mBasemost = e.CallMethod.GetBasemostMethod(null); int vTableIndex = this.resolver.VirtualCallIndices[mBasemost]; this.Visit(e.RuntimeType); this.js.AppendFormat(".{0}[{1}]", this.resolver.TypeDataNames[TypeData.VTable], vTableIndex); this.CallAppendArgs(e); } return(e); }
protected override ICode VisitCall(ExprCall e) { var expr = this.HandleCall(e, (obj, args) => new ExprCall(e.Ctx, e.CallMethod, obj, args, e.IsVirtualCall, e.ConstrainedType, e.Type)); var res = JsResolver.ResolveCallSite(expr); if (res != null) { return(this.Visit(res)); } if (expr.ConstrainedType != null) { if (expr.ConstrainedType.IsValueType) { // Map constrained virtual call to a method on a value-type, to a non-virtual call. // This is important as it prevents having to box the value-type, which is expensive var impl = expr.ConstrainedType.EnumResolvedMethods().FirstOrDefault(x => x.MatchMethodOnly(expr.CallMethod)); if (impl != null) { var constrainedCall = new ExprCall(expr.Ctx, impl, expr.Obj, expr.Args, false, null, expr.Type); return(constrainedCall); } else { throw new Exception(); } } } if (expr.IsVirtualCall) { var ctx = expr.Ctx; var objIsVar = expr.Obj.IsVar(); var temp = objIsVar ? null : new ExprVarLocal(ctx, expr.Obj.Type); var getTypeObj = objIsVar ? expr.Obj : new ExprAssignment(ctx, temp, expr.Obj); var getType = new ExprCall(ctx, typeof(object).GetMethod("GetType"), getTypeObj); var eJsVCall = new ExprJsVirtualCall(ctx, expr.CallMethod, getType, temp ?? expr.Obj, expr.Args); return(eJsVCall); } return(expr); }
protected virtual ICode VisitJsVirtualCall(ExprJsVirtualCall e) { this.ThrowOnNoOverride(); var runtimeType = (Expr)this.Visit(e.RuntimeType); var objRef = (Expr)this.Visit(e.ObjRef); var args = this.HandleList(e.Args, x => (Expr)this.Visit(x)); if (runtimeType != e.RuntimeType || objRef != e.ObjRef || args != null) { return new ExprJsVirtualCall(e.Ctx, e.CallMethod, runtimeType, objRef, args ?? e.Args); } else { return e; } }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { this.calls.Add(e); return(base.VisitJsVirtualCall(e)); }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { return this.HandleCall(e, (obj, args) => new ExprJsVirtualCall(e.Ctx, e.CallMethod, e.RuntimeType, obj, args)); }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { var isIFaceCall = e.CallMethod.DeclaringType.Resolve().IsInterface; if (isIFaceCall) { var iTableIndex = this.resolver.InterfaceCallIndices[e.CallMethod]; var iFaceName = this.resolver.InterfaceNames[e.CallMethod.DeclaringType]; this.Visit(e.RuntimeType); this.js.AppendFormat(".{0}[{1}]", iFaceName, iTableIndex); this.CallAppendArgs(e); } else { var mBasemost = e.CallMethod.GetBasemostMethod(null); int vTableIndex = this.resolver.VirtualCallIndices[mBasemost]; this.Visit(e.RuntimeType); this.js.AppendFormat(".{0}[{1}]", this.resolver.TypeDataNames[TypeData.VTable], vTableIndex); this.CallAppendArgs(e); } return e; }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { // Need to add the type of the base method of the virtual call, so // the virtual method table is generated correctly this.types.Add(e.CallMethod.DeclaringType); return base.VisitJsVirtualCall(e); }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { this.code.Append("vCall:"); this.Visit(e.Obj); this.code.Append(e.CallMethod.Name); this.code.Append("("); if (e.Args.Any()) { foreach (var arg in e.Args) { this.Visit(arg); this.code.Append(", "); } this.code.Length -= 2; } this.code.Append(")"); return e; }
protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e) { return(this.HandleCall(e, (obj, args) => new ExprJsVirtualCall(e.Ctx, e.CallMethod, e.RuntimeType, obj, args))); }