Inheritance: Expr, ICall
コード例 #1
0
 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);
     }
 }
コード例 #2
0
 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);
     }
 }
コード例 #3
0
 protected override ICode VisitNewObj(ExprNewObj e) {
     return this.HandleCall(e, (obj, args) => new ExprNewObj(e.Ctx, e.CallMethod, args));
 }
コード例 #4
0
 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;
 }
コード例 #5
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);
        }
コード例 #6
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);
        }
コード例 #7
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);
        }
コード例 #8
0
            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;
            }
コード例 #9
0
 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);
 }
コード例 #10
0
 protected override ICode VisitNewObj(ExprNewObj e) {
     this.code.AppendFormat("new ");
     this.VisitCall(e, true);
     return e;
 }
コード例 #11
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);
 }