public Stmt GetImpl(Ctx ctx)
            {
                var obj             = ctx.MethodParameter(0, "obj");
                var toType          = ctx.MethodParameter(1);
                var callCanAssignTo = new ExprCall(ctx, (Func <object, Type, bool>)CanAssignTo, null, obj.Expr, toType).Named("callCanAssignTo");
                var mCtorEx         = ctx.Module.Import(typeof(InvalidCastException).GetConstructor(new[] { typeof(string) }));
                var mGetType        = ctx.Module.Import(typeof(object).GetMethod("GetType"));
                var getTypeCall     = new ExprCall(ctx, mGetType, obj.Expr);
                var msgParts        = new Expr[] {
                    new ExprLiteral(ctx, "Unable to cast object of type '", ctx.String),
                    new ExprCall(ctx, typeof(Type).GetProperty("FullName").GetMethod, getTypeCall),
                    new ExprLiteral(ctx, "' to type '", ctx.String),
                    new ExprCall(ctx, typeof(Type).GetProperty("FullName").GetMethod, toType),
                    new ExprLiteral(ctx, "'.", ctx.String)
                };
                var msg    = msgParts.Aggregate((a, b) => new ExprBinary(ctx, BinaryOp.Add, ctx.String, a, b));
                var ctorEx = new ExprNewObj(ctx, mCtorEx, msg).Named("callCtorEx");
                var js     = @"
if (callCanAssignTo) return obj;
throw callCtorEx
";
                var stmt   = new StmtJsExplicit(ctx, js, callCanAssignTo, obj, ctorEx);

                return(stmt);
            }
Exemple #2
0
        public static Stmt get_Value(Ctx ctx)
        {
            var excCtor = ctx.Module.Import(typeof(InvalidOperationException).GetConstructor(Type.EmptyTypes));
            var invalidOperationException      = new ExprNewObj(ctx, excCtor);
            var throwInvalidOperationException = new StmtThrow(ctx, invalidOperationException);
            var cond    = new ExprJsExplicit(ctx, "(this === null)", ctx.Boolean, ctx.ThisNamed);
            var throwIf = new StmtIf(ctx, cond, throwInvalidOperationException, null);
            var ret     = new StmtReturn(ctx, ctx.This);
            var stmt    = new StmtBlock(ctx, throwIf, ret);

            return(stmt);
        }
        protected override ICode VisitNewObj(ExprNewObj e)
        {
            var expr = this.HandleCall(e, (obj, args) => new ExprNewObj(e.Ctx, e.CallMethod, args));
            var res  = JsResolver.ResolveCallSite(expr);

            if (res == null)
            {
                return(expr);
            }
            else
            {
                return(this.Visit(res));
            }
        }
Exemple #4
0
        private Stmt NewObj(Instruction inst)
        {
            var ctorRef  = ((MethodReference)inst.Operand).FullResolve(this.ctx);
            var numArgs  = ctorRef.Parameters.Count;
            var argExprs = new Expr[numArgs];

            for (int i = numArgs - 1; i >= 0; i--)
            {
                argExprs[i] = this.stack.Pop();
            }
            var expr = new ExprNewObj(this.ctx, ctorRef, argExprs);

            return(this.SsaLocalAssignment(expr));
        }
        protected override ICode VisitNewObj(ExprNewObj e)
        {
            var isDelegate = e.CallMethod.DeclaringType.EnumThisAllBaseTypes().Any(x => x.IsDelegate());

            if (isDelegate)
            {
                var ctx  = e.Ctx;
                var mRef = ((ExprMethodReference)e.Args.ElementAt(1)).Method;
                var obj  = mRef.HasThis ? e.Args.ElementAt(0) : null;
                return(new ExprJsDelegateCtor(ctx, e.Type, obj, mRef));
            }
            else
            {
                return(base.VisitNewObj(e));
            }
        }
        public static Stmt CreateComparer(Ctx ctx)
        {
            var type = ((GenericInstanceType)ctx.MRef.DeclaringType).GenericArguments[0];

            if (type.IsByte())
            {
                throw new Exception();
            }
            var iEquatable = ctx.Module.Import(typeof(IEquatable <>)).MakeGeneric(type);

            if (type.DoesImplement(iEquatable))
            {
                var t        = Type.GetType("System.Collections.Generic.GenericEqualityComparer`1");
                var compType = ctx.Module.Import(t).MakeGeneric(type);
                var ctor     = compType.EnumResolvedMethods().First(x => x.Resolve().IsConstructor);
                var ctorExpr = new ExprNewObj(ctx, ctor);
                return(new StmtReturn(ctx, ctorExpr));
            }
            throw new NotImplementedException();
        }
        protected override ICode VisitNewObj(ExprNewObj e)
        {
            var name = this.resolver.MethodNames[e.CallMethod];

            this.js.Append(name);
            this.js.Append("({");
            if (!e.Type.IsValueType)
            {
                this.js.Append("_:");
                this.js.Append(this.resolver.TypeNames[e.Type]);
            }
            this.js.Append("}");
            foreach (var arg in e.Args)
            {
                this.js.Append(", ");
                this.Visit(arg);
            }
            this.js.Append(")");
            return(e);
        }
            public Stmt GetImpl(Ctx ctx)
            {
                // If obj==null throw NullRefEx
                // If obj.Type not assignable to e.Type throw InvalidCastEx
                // otherwise unbox
                var obj           = ctx.MethodParameter(0, "obj");
                var type          = ((GenericInstanceMethod)ctx.MRef).GenericArguments[0];
                var nullRefExCtor = ctx.Module.Import(typeof(NullReferenceException).GetConstructor(new[] { typeof(string) }));
                var nullRefEx     = new ExprNewObj(ctx, nullRefExCtor, new ExprLiteral(ctx, "Object reference not set to an instance of an object.", ctx.String)).Named("nullRefEx");
                var canAssign     = new ExprCall(ctx, ((Func <object, Type, bool>)CanAssignTo).Method, null, obj.Expr, new ExprJsTypeVarName(ctx, type)).Named("canAssignCall");
                var invCastExCtor = ctx.Module.Import(typeof(InvalidCastException).GetConstructor(new[] { typeof(string) }));
                var invCastEx     = new ExprNewObj(ctx, invCastExCtor, new ExprLiteral(ctx, "Specified cast is not valid.", ctx.String)).Named("invCastEx");
                var js            = @"
if (!obj) throw nullRefEx;
if (!canAssignCall) throw invCastEx;
return obj.v;
";
                var stmt          = new StmtJsExplicit(ctx, js, obj, nullRefEx, canAssign, invCastEx);

                return(stmt);
            }
            public Stmt GetImpl(Ctx ctx)
            {
                // If obj==null create Nullable with hasValue=false
                // If obj.Type not assignable to e.InnerType throw InvalidCastEx
                var obj   = ctx.MethodParameter(0, "obj");
                var type  = ((GenericInstanceMethod)ctx.MRef).GenericArguments[0];
                var nType = type.MakeNullable();
                //var nameHasValue = new ExprJsFieldVarName(ctx, nType.GetField("hasValue")).Named("hasValue");
                //var nameValue = new ExprJsFieldVarName(ctx, nType.GetField("value")).Named("value");
                //var defaultValue = new ExprDefaultValue(ctx, type).Named("defaultValue");
                var canAssignCall = new ExprCall(ctx, ((Func <object, Type, bool>)CanAssignTo).Method, null, obj.Expr, new ExprJsTypeVarName(ctx, type)).Named("canAssignCall");
                var invCastExCtor = ctx.Module.Import(typeof(InvalidCastException).GetConstructor(new[] { typeof(string) }));
                var invCastEx     = new ExprNewObj(ctx, invCastExCtor, new ExprLiteral(ctx, "Specified cast is not valid.", ctx.String)).Named("invCastEx");
                var js            = @"
if (obj == null) return null;
if (!canAssignCall) throw invCastEx;
return obj.v;
";
                var stmt          = new StmtJsExplicit(ctx, js, obj, canAssignCall, invCastEx);

                return(stmt);
            }
        public static Stmt CreateComparer(Ctx ctx)
        {
            var type      = ((GenericInstanceType)ctx.MRef.DeclaringType).GenericArguments[0];
            var iComparer = ctx.Module.Import(typeof(IComparer <>)).MakeGeneric(type);

            if (type.DoesImplement(iComparer))
            {
                var t        = Type.GetType("System.Collections.Generic.GenericComparer`1");
                var compType = ctx.Module.Import(t).MakeGeneric(type);
                var ctor     = compType.EnumResolvedMethods().First(x => x.Resolve().IsConstructor);
                var ctorExpr = new ExprNewObj(ctx, ctor);
                return(new StmtReturn(ctx, ctorExpr));
            }
            var iComparable = ctx.Module.Import(typeof(IComparable <>)).MakeGeneric(type);

            if (type.DoesImplement(iComparable))
            {
                var compType = ctx.Module.Import(typeof(ComparableComparer <>)).MakeGeneric(type);
                var ctor     = compType.EnumResolvedMethods().First(x => x.Resolve().IsConstructor);
                var ctorExpr = new ExprNewObj(ctx, ctor);
                return(new StmtReturn(ctx, ctorExpr));
            }
            return(new StmtThrow(ctx, ctx.Literal(null, ctx.Object)));
        }
Exemple #11
0
 protected override ICode VisitNewObj(ExprNewObj e)
 {
     this.calls.Add(e);
     return(base.VisitNewObj(e));
 }
        protected override ICode VisitNewObj(ExprNewObj e)
        {
            var args = e.Args.Select((x, i) => this.Convert(x, e.CallMethod.Parameters[i].ParameterType.FullResolve(e.CallMethod))).ToArray();

            return(new ExprNewObj(e.Ctx, e.CallMethod, args));
        }
 protected virtual ICode VisitNewObj(ExprNewObj e)
 {
     return(this.HandleCall(e, (obj, args) => new ExprNewObj(e.Ctx, e.CallMethod, args)));
 }
Exemple #14
0
        public static Stmt FormatDouble(Ctx ctx)
        {
            var value     = ctx.MethodParameter(0, "value");
            var format    = ctx.MethodParameter(1, "format");
            var newFmtEx  = new ExprNewObj(ctx, ctx.Module.Import(typeof(FormatException).GetConstructor(Type.EmptyTypes))).Named("newFmtEx");
            var valuePos  = ctx.Local(ctx.Int32, "valuePos");
            var precision = ctx.Local(ctx.Int32.MakeNullable(), "precision");
            var fmt0      = ctx.Local(ctx.String, "fmt0");
            var s         = ctx.Local(ctx.String, "s");
            var parts     = ctx.Local(ctx.String.MakeArray(), "parts");
            var i         = ctx.Local(ctx.Int32, "i");
            var js        = @"
if (isNaN(value)) return 'NaN';
if (value === Number.POSITIVE_INFINITY) return 'Infinity';
if (value === Number.NEGATIVE_INFINITY) return '-Infinity';
format = format || 'G';
valuePos = Math.abs(value);
precision = format.length > 1 ? +format.substr(1) : null;
fmt0 = format.charAt(0);
switch (fmt0) {
case 'g':
case 'G':
    s = valuePos.toPrecision(precision || 15);
    if (s.indexOf('e') >= 0) {
        parts = s.split('e');
        parts[0] = parts[0].replace(/(\d)\.?0+$/, '$1');
        parts[1] = parts[1].replace(/^\+(\d)$/, '+0$1');
        s = parts.join(fmt0 === 'g' ? 'e' : 'E');
    } else if (s.indexOf('.') >= 0) {
        s = s.replace(/(\d)\.?0+$/g, '$1');
    }
    break;
case 'f':
case 'F':
case 'n':
case 'N':
    s = valuePos.toExponential(14);
    parts = s.replace('.', '').split('e');
    i = Number(parts[1]) + 1;
    s = parts[0];
    if (i <= 0) {
        s = '0' + Array(-i + 1).join('0') + s;
        i = 1;
    }
    if (precision === null) precision = 2;
    i += precision;
    if (s.length <= i) {
        s += Array(i - s.length + 1).join('0');
    } else {
        var needInc = (+s.charAt(i)) >= 5;
        s = s.substr(0, i);
        var cs = s.split('');
        if (needInc) {
            for (var j = cs.length - 1; j >= 0; j--) {
                if (++cs[j] < 10) {
                    needInc = false;
                    break;
                }
                cs[j] = 0;
            }
            if (needInc) {
                cs.unshift(1);
                i++;
            }
        }
        s = cs.join('');
    }
    i -= precision;
    if (fmt0 === 'n' || fmt0 === 'N') {
        s = s.substr(0, i).replace(/(\d)(?=(\d{3})+$)/g, '$1,') + (precision > 0 ? '.' + s.substr(i) : '');
    } else {
        s = s.substr(0, i) + (precision > 0 ? '.' + s.substr(i) : '');
    }
    break;
default:
    throw newFmtEx;
}
return value < 0 ? '-' + s : s;
";

            return(new StmtJsExplicit(ctx, js, value, format, newFmtEx, valuePos, precision, fmt0, s, parts, i));
        }
            public Stmt GetImpl(Ctx ctx)
            {
                var a           = ctx.MethodParameter(0, "a");
                var b           = ctx.MethodParameter(1, "b");
                var u           = ctx.Local(ctx.Int32.MakeArray(), "u");
                var v           = ctx.Local(ctx.Int32.MakeArray(), "v");
                var m           = ctx.Local(ctx.Int32, "m");
                var n           = ctx.Local(ctx.Int32, "n");
                var r           = ctx.Local(ctx.Int32.MakeArray(), "r");
                var q           = ctx.Local(ctx.Int32.MakeArray(), "q");
                var i           = ctx.Local(ctx.Int32, "i");
                var j           = ctx.Local(ctx.Int32, "j");
                var k           = ctx.Local(ctx.Int32, "k");
                var l           = ctx.Local(ctx.Int32, "l");
                var p           = ctx.Local(ctx.Int32, "p");
                var t           = ctx.Local(ctx.Int32, "t");
                var s           = ctx.Local(ctx.Int32, "s");
                var x           = ctx.Local(ctx.Int32, "x");
                var qhat        = ctx.Local(ctx.Int32, "qhat");
                var rhat        = ctx.Local(ctx.Int32, "rhat");
                var mask        = ctx.Literal(0xffff, ctx.Int32, "mask");
                var limit       = ctx.Literal(0x10000, ctx.Int32, "limit");
                var divByZeroEx = new ExprNewObj(ctx, ctx.Module.Import(typeof(DivideByZeroException).GetConstructor(Type.EmptyTypes))).Named("divByZeroEx");
                var js          = @"
v = [b[1] & mask, b[1] >>> 16, b[0] & mask, b[0] >>> 16];
while (v[v.length - 1] === 0) {
    v = v.slice(0, -1);
    if (v.length === 0) throw divByZeroEx;
}
n = v.length;
u = [a[1] & mask, a[1] >>> 16, a[0] & mask, a[0] >>> 16];
while (u[u.length - 1] === 0 && u.length > n) u = u.slice(0, -1);
m = u.length;
r = [0, 0, 0, 0];
q = [0, 0, 0, 0];
if (n === 1) {
    k = 0;
    for (j = m - 1; j >= 0; j--) {
        l = k * limit + u[j]
        q[j] = (l / v[0]) >>> 0;
        k = l - q[j] * v[0];
    }
    r[0] = k;
} else {
    x = v[n - 1];
    s = 16;
    while (x > 0) {
        x >>>= 1;
        s--;
    }
    l = 0;
    for (i = n - 1; i > 0; i--) v[i] = ((v[i] << s) | (v[i - 1] >> (16 - s))) & mask;
    v[0] = (v[0] << s) & mask;
    u.push(0);
    for (i = m; i> 0; i--) u[i] = ((u[i] << s) | (u[i - 1] >> (16 - s))) & mask;
    u[0] = (u[0] << s) & mask;
    for (j = m - n; j >= 0; j--) {
        l = u[j + n] * limit + u[j + n - 1];
        qhat = (l / v[n - 1]) >>> 0;
        rhat = l - qhat * v[n - 1];
        for (;;) {
            if (qhat >= limit || qhat * v[n - 2] > limit * rhat + u[j + n - 2]) {
                qhat--;
                rhat += v[n - 1];
                if (rhat < limit) continue;
            }
            break;
        }
        k = 0;
        for (i = 0; i < n; i++) {
            p = qhat * v[i];
            t = u[i + j] - k - (p & mask);
            u[i + j] = t & mask;
            k = (p >> 16) - (t >> 16);
        }
        t = u[j + n] - k;
        u[j + n] = t;
        q[j] = qhat;
        if (t < 0) {
            q[j]--;
            k = 0;
            for (i = 0; i < n; i++) {
                t = u[i + j] + n[i] + k;
                u[i + j] = t & mask;
                k = t >> 16;
            }
            u[j + n] += k;
        }
    }
    for (i = 0; i< n; i++) {
        r[i] = ((u[i] >> s) | (u[i + 1] << (16 - s))) & mask;
    }
}
return [[q[2] + q[3] * limit, q[0] + q[1] * limit], [r[2] + r[3] * limit, r[0] + r[1] * limit]];
";
                var stmt        = new StmtJsExplicit(ctx, js, a, b, u, v, m, n, r, q, i, j, k, l, p, s, t, qhat, rhat, mask, limit, divByZeroEx);

                return(stmt);
            }
Exemple #16
0
        public static Stmt FormatInt64(Ctx ctx)
        {
            var value         = ctx.MethodParameter(0, "value");
            var format        = ctx.MethodParameter(1, "format");
            var neg           = ctx.Local(ctx.Boolean, "neg");
            var precision     = ctx.Local(ctx.Int32.MakeNullable(), "precision");
            var fmt0          = ctx.Local(ctx.String, "fmt0");
            var i             = ctx.Local(ctx.Int32, "i");
            var s             = ctx.Local(ctx.String, "s");
            var ss            = ctx.Local(ctx.String, "ss");
            var c             = ctx.Local(ctx.String, "c");
            var inc           = ctx.Local(ctx.Boolean, "inc");
            var divMod10      = ctx.Local(ctx.Int64.MakeArray(), "divMod10");
            var valueDivMod10 = new ExprCall(ctx, (Func <UInt64, UInt64, object>)_Int64UInt64.UInt64DivRem, null, value.Expr, ctx.Literal(10L)).Named("valueDivMod10");
            var valueNeg      = new ExprCall(ctx, (Func <Int64, Int64, Int64>)_Int64.Subtract, null, ctx.Literal(0L), value.Expr).Named("valueNeg");
            var sLen          = ctx.Local(ctx.Int32, "sLen");
            var newFmtEx      = new ExprNewObj(ctx, ctx.Module.Import(typeof(FormatException).GetConstructor(Type.EmptyTypes))).Named("newFmtEx");
            var js            = @"
format = format || 'G';
precision = format.length > 1 ? +format.substr(1) : null;
fmt0 = format.charAt(0);
if (fmt0 === 'x' || fmt0 === 'X') {
    s = value[1].toString(16);
    if (value[0] !== 0) {
        s = value[0].toString(16) + Array(9 - s.length).join('0') + s;
    }
    if (fmt0 === 'X') {
        s = s.toUpperCase();
    }
    if (precision !== null && precision > s.length) {
        s = Array(precision - s.length + 1).join('0') + s;
    }
    return s;
}
if (value[0] === 0 && value[1] === 0) {
    s = '0';
} else if (value[0] === 0x80000000 && value[1] === 0) {
    s = '9223372036854775808';
    neg = true;
} else {
    if (value[0] >= 0x80000000) {
        value = valueNeg;
        neg = true;
    }
    s = '';
    while (value[0] !== 0 || value[1] !== 0) {
        divMod10 = valueDivMod10;
        value = divMod10[0];
        s = String.fromCharCode(48 + divMod10[1][1]) + s;
    }
}
switch (fmt0) {
case 'g':
case 'G':
    if (precision !== null && precision < s.length && precision > 0) {
        sLen = s.length;
        inc = +(s.charAt(precision)) >= 5;
        s = s.substr(0, precision);
        ss = '';
        for (i = precision - 1; i >= 0; i--) {
            c = s.charAt(i);
            if (inc) {
                c = (+c) + 1;
                if (c > 9) {
                    c = 0;
                } else {
                    inc = false;
                }
                ss = String.fromCharCode(48 + c) + ss;
            } else {
                ss = c + ss;
            }
        }
        if (inc) {
            sLen++;
            ss = '1' + ss.substr(0, ss.length - 1);
        }
        if (ss.length > 1) {
            ss = ss.charAt(0) + '.' + ss.substr(1);
        }
        s = ss.replace(/(\d)\.?0+$/, '$1');
        s += (fmt0 === 'g' ? 'e' : 'E') + '+' + (sLen - 1).toFixed().replace(/^(\d)$/, '0$1');;
    }
    break;
case 'd':
case 'D':
    if (precision !== null && precision > s.length) {
        s = Array(precision - s.length + 1).join('0') + s;
    }
    break;
case 'n':
case 'N':
    if (precision === null) precision = 2;
    s = s.replace(/(\d)(?=(\d{3})+$)/g, '$1,');
    if (precision > 0) {
        s += '.' + Array(precision + 1).join('0');
    }
    break;
default:
    throw newFmtEx;
}
return neg ? '-' + s : s;
";

            return(new StmtJsExplicit(ctx, js, value, format, neg, precision, fmt0, i, s, ss, c, inc, divMod10, valueDivMod10, valueNeg, sLen, newFmtEx));
        }
 protected override ICode VisitNewObj(ExprNewObj e)
 {
     this.code.AppendFormat("new ");
     this.VisitCall(e, true);
     return(e);
 }
Exemple #18
0
        public static Stmt FormatInt32(Ctx ctx)
        {
            var value     = ctx.MethodParameter(0, "value");
            var format    = ctx.MethodParameter(1, "format");
            var newFmtEx  = new ExprNewObj(ctx, ctx.Module.Import(typeof(FormatException).GetConstructor(Type.EmptyTypes))).Named("newFmtEx");
            var valuePos  = ctx.Local(ctx.Int32, "valuePos");
            var precision = ctx.Local(ctx.Int32.MakeNullable(), "precision");
            var fmt0      = ctx.Local(ctx.String, "fmt0");
            var s         = ctx.Local(ctx.String, "s");
            var parts     = ctx.Local(ctx.String.MakeArray(), "parts");
            var js        = @"
format = format || 'G';
valuePos = Math.abs(value);
precision = format.length > 1 ? +format.substr(1) : null;
fmt0 = format.charAt(0);
switch (fmt0) {
case 'd':
case 'D':
    s = valuePos.toString();
    if (precision !== null && precision > s.length) {
        s = Array(precision - s.length + 1).join('0') + s;
    }
    break;
case 'g':
case 'G':
    s = valuePos.toString();
    if (precision !== null && precision < s.length && precision > 0) {
        s = valuePos.toPrecision(precision);
        parts = s.split('e');
        parts[0] = parts[0].replace(/(\d)\.?0+$/, '$1');
        parts[1] = parts[1].replace(/^\+(\d)$/, '+0$1');
        s = parts.join(fmt0 === 'g' ? 'e' : 'E');
    }
    break;
case 'n':
case 'N':
    if (precision === null) precision = 2;
    s = valuePos.toFixed(precision);
    parts = s.split('.');
    parts[0] = parts[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
    s = parts.join('.');
    break;
case 'x':
case 'X':
    if (value < 0) {
        value += 0x100000000;
    }
    s = value.toString(16);
    if (fmt0 === 'X') {
        s = s.toUpperCase();
    }
    if (precision !== null && precision > s.length) {
        s = Array(precision - s.length + 1).join('0') + s;
    }
    break;
default:
    throw newFmtEx;
}
return value < 0 ? '-' + s : s;
";

            return(new StmtJsExplicit(ctx, js, value, format, newFmtEx, valuePos, precision, fmt0, s, parts));
        }