상속: Expr, ICall
예제 #1
0
 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;
 }
예제 #3
0
        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));
        }
예제 #4
0
        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);
 }
예제 #6
0
        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);
        }
예제 #8
0
 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;
     }
 }
예제 #9
0
 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));
 }
예제 #11
0
 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);
 }
예제 #13
0
 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;
 }
예제 #14
0
 protected override ICode VisitJsVirtualCall(ExprJsVirtualCall e)
 {
     return(this.HandleCall(e, (obj, args) => new ExprJsVirtualCall(e.Ctx, e.CallMethod, e.RuntimeType, obj, args)));
 }