diff --git a/.gitignore b/.gitignore index 80d0a02c4..f924989de 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,10 @@ Tests.DCE/obj Tests.DCE//bin JSIL.Libraries/node_modules JSIL.Libraries/obj +JSIL.Libraries/Generated +JSIL.Libraries/bin Libraries/ .vs/ -/mono \ No newline at end of file +/mono +JSIL.mscorlib/obj/ +JSIL.mscorlib/bin/ \ No newline at end of file diff --git a/Compiler/Compiler.csproj b/Compiler/Compiler.csproj index a43890d7f..324d4902a 100644 --- a/Compiler/Compiler.csproj +++ b/Compiler/Compiler.csproj @@ -96,7 +96,7 @@ Designer - Always + PreserveNewest diff --git a/Compiler/defaults.jsilconfig b/Compiler/defaults.jsilconfig index c2d19cb9d..03e427960 100644 --- a/Compiler/defaults.jsilconfig +++ b/Compiler/defaults.jsilconfig @@ -3,7 +3,7 @@ "ProxyWarnings": false, "Assemblies": { "Stubbed": [ - "mscorlib,", + "^mscorlib,", "^System,", "^System\\.(.+),", "^Microsoft\\.(.+),", diff --git a/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.BitConverter.js b/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.BitConverter.js index 7ad90c2aa..d2bde21e8 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.BitConverter.js +++ b/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.BitConverter.js @@ -301,6 +301,13 @@ JSIL.ImplementExternals("System.BitConverter", function ($) { (new JSIL.MethodSignature($.Double, [$jsilcore.TypeRef("System.Array", [$.Byte]), $.Int32], [])), $jsilcore.BytesToDouble ); + + $.Method({ Static: true, Public: true }, "DoubleToInt64Bits", + (new JSIL.MethodSignature($.Int64, [$.Double], [])), + function DoubleToInt64Bits(double) { + return $jsilcore.BytesToInt64($jsilcore.BytesFromDouble(double), 0); + } + ); }); //? if ('GENERATE_STUBS' in __out) { diff --git a/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Double.js b/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Double.js index 92729ed6d..88f76d0f0 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Double.js +++ b/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Double.js @@ -6,7 +6,7 @@ JSIL.ImplementExternals( return (typeof (value) === "number"); }); - $jsilcore.$MakeParseExternals($, $.Single, $jsilcore.$ParseFloat, $jsilcore.$TryParseFloat); + $jsilcore.$MakeParseExternals($, $.Double, $jsilcore.$ParseFloat, $jsilcore.$TryParseFloat); $.Constant({ Public: true, Static: true }, "MinValue", -1.7976931348623157E+308); $.Constant({ Public: true, Static: true }, "MaxValue", 1.7976931348623157E+308); diff --git a/JSIL.Libraries/Includes/Bootstrap/Core/Utils/$jsilcore.$MakeParseExternals.js b/JSIL.Libraries/Includes/Bootstrap/Core/Utils/$jsilcore.$MakeParseExternals.js index 86c82e4d0..9271f31cf 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Core/Utils/$jsilcore.$MakeParseExternals.js +++ b/JSIL.Libraries/Includes/Bootstrap/Core/Utils/$jsilcore.$MakeParseExternals.js @@ -10,6 +10,14 @@ $jsilcore.$MakeParseExternals = function ($, type, parse, tryParse) { parse ); + $.Method({ Static: true, Public: true }, "Parse", + (new JSIL.MethodSignature(type, [$.String, $jsilcore.TypeRef("System.IFormatProvider")], [])), + function (input, formatProvider) { + // TODO: Really use fromat provider + return parse(input, null); + } + ); + $.Method({ Static: true, Public: true }, "TryParse", (new JSIL.MethodSignature($.Boolean, [$.String, $jsilcore.TypeRef("JSIL.Reference", [type])], [])), tryParse diff --git a/JSIL.Libraries/Includes/Bootstrap/Int/Classes/System.UInt64.js b/JSIL.Libraries/Includes/Bootstrap/Int/Classes/System.UInt64.js index fd8e8334f..246bdeb8b 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Int/Classes/System.UInt64.js +++ b/JSIL.Libraries/Includes/Bootstrap/Int/Classes/System.UInt64.js @@ -307,7 +307,8 @@ JSIL.ImplementExternals("System.UInt64", function ($) { $.Method({ Static: true, Public: false }, "FromNumber", (new JSIL.MethodSignature($.Type, [$.Double], [])), function UInt64_FromNumber(n) { - return me().FromNumberImpl(n, ctor); + var sum = n < 0 ? 0x100000000 : 0; + return me().FromNumberImpl(sum + n, ctor); }); // Not present in mscorlib diff --git a/JSIL.Libraries/Includes/Bootstrap/Resources/Classes/System.Globalization.CultureInfo.js b/JSIL.Libraries/Includes/Bootstrap/Resources/Classes/System.Globalization.CultureInfo.js index 53c09a7aa..144f14bf5 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Resources/Classes/System.Globalization.CultureInfo.js +++ b/JSIL.Libraries/Includes/Bootstrap/Resources/Classes/System.Globalization.CultureInfo.js @@ -75,7 +75,23 @@ JSIL.ImplementExternals("System.Globalization.CultureInfo", function ($) { return $jsilcore.System.Globalization.CultureInfo.GetCultureInfo(name); } ); - + + $.Method({ Static: false, Public: true }, "get_IsReadOnly", + (new JSIL.MethodSignature($.Boolean, [], [])), + function get_IsReadOnly() { + return true; + } + ); + + $.Method({ Static: false, Public: true }, "get_NumberFormat", + (new JSIL.MethodSignature($jsilcore.TypeRef("System.Globalization.NumberFormatInfo"), [], [])), + function get_NumberFormat() { + if (this.numInfo === null) { + this.numInfo = new $jsilcore.System.Globalization.NumberFormatInfo(); + } + return this.numInfo; + } + ); }); JSIL.ImplementExternals("System.Globalization.CultureInfo", function ($) { @@ -93,4 +109,8 @@ JSIL.ImplementExternals("System.Globalization.CultureInfo", function ($) { return $jsilcore.getCurrentUICultureImpl(); } ); -}); \ No newline at end of file +}); + +JSIL.MakeClass("System.Object", "System.Globalization.CultureInfo", true, [], function ($) { + $.Field({ Public: false, Static: false }, "numInfo", $jsilcore.TypeRef("System.Globalization.NumberFormatInfo")); +}) \ No newline at end of file diff --git a/JSIL.Libraries/Includes/Bootstrap/Resources/Main.js b/JSIL.Libraries/Includes/Bootstrap/Resources/Main.js index 776b629ff..e64cafc4e 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Resources/Main.js +++ b/JSIL.Libraries/Includes/Bootstrap/Resources/Main.js @@ -8,7 +8,7 @@ if (!$jsilcore) $jsilcore.getCurrentUICultureImpl = function () { var language; - var svc = JSIL.Host.getService("window", false); + var svc = JSIL.Host.getService("window", true); if (svc) { language = svc.getNavigatorLanguage() || "en-US"; diff --git a/JSIL.Libraries/Includes/Bootstrap/Text/Classes/System.Text.StringBuilder.js b/JSIL.Libraries/Includes/Bootstrap/Text/Classes/System.Text.StringBuilder.js index 3d88afa1a..1a7b5d931 100644 --- a/JSIL.Libraries/Includes/Bootstrap/Text/Classes/System.Text.StringBuilder.js +++ b/JSIL.Libraries/Includes/Bootstrap/Text/Classes/System.Text.StringBuilder.js @@ -284,6 +284,14 @@ JSIL.ImplementExternals("System.Text.StringBuilder", function ($) { } ); + $.Method({ Static: false, Public: true }, "Remove", + (new JSIL.MethodSignature($.Type, [$.Int32, $.Int32], [])), + function Remove(startIndex, length) { + this._str = this._str.substr(0, startIndex) + this._str.substring(startIndex + length, length); + return this; + } + ); + var replace = function (self, oldText, newText, startIndex, count) { var prefix = self._str.substr(0, startIndex); var suffix = self._str.substr(startIndex + count); @@ -328,6 +336,35 @@ JSIL.ImplementExternals("System.Text.StringBuilder", function ($) { } ); + var insert = function (self, string, startIndex, count) { + while (startIndex > self._str.length - 1 && self._str.length < self._capacity) { + self._str += "\0"; + } + + var suffix = self._str.substr(startIndex); + self._str = self._str.substr(0, startIndex); + for (var i = 0; i < count; i++) { + self._str += string; + } + self._str += suffix; + self._capacity = Math.max(self._capacity, self._str.length); + return self; + }; + + $.Method({ Static: false, Public: true }, "Insert", + (new JSIL.MethodSignature($.Type, [$.Int32, $.String], [])), + function Insert(index, value) { + return insert(this, index, value, 1); + } + ); + + $.Method({ Static: false, Public: true }, "Insert", + (new JSIL.MethodSignature($.Type, [$.Int32, $.String, $.Int32], [])), + function Insert(index, value, count) { + return insert(this, index, value, count); + } + ); + $.Method({ Static: false, Public: true }, "set_Length", (new JSIL.MethodSignature(null, [$.Int32], [])), function set_Length(value) { @@ -355,6 +392,9 @@ JSIL.ImplementExternals("System.Text.StringBuilder", function ($) { $.Method({ Static: false, Public: true }, "set_Chars", (new JSIL.MethodSignature(null, [$.Int32, $.Char], [])), function set_Chars(i, value) { + while (i > this._str.length - 1) { + this._str += "\0"; + } this._str = this._str.substr(0, i) + value + diff --git a/JSIL.Libraries/JSIL.Libraries.csproj b/JSIL.Libraries/JSIL.Libraries.csproj index 75b2668a0..10b54ee0a 100644 --- a/JSIL.Libraries/JSIL.Libraries.csproj +++ b/JSIL.Libraries/JSIL.Libraries.csproj @@ -14,7 +14,7 @@ Properties ClassLibrary1 ClassLibrary1 - v4.0 + v4.5 512 @@ -22,7 +22,7 @@ true full false - .\ + bin\ DEBUG;TRACE prompt 4 @@ -30,7 +30,7 @@ pdbonly true - .\ + bin\ TRACE prompt 4 @@ -325,7 +325,12 @@ - + + + {aef2633e-e92c-4a0d-b8e0-a072ed404af7} + JSIL.mscorlib + + diff --git a/JSIL.Libraries/Sources/JSIL.Bootstrap.Int64.js b/JSIL.Libraries/Sources/JSIL.Bootstrap.Int64.js index 81b640a30..ea7eacd7b 100644 --- a/JSIL.Libraries/Sources/JSIL.Bootstrap.Int64.js +++ b/JSIL.Libraries/Sources/JSIL.Bootstrap.Int64.js @@ -1,999 +1,2 @@ -"use strict"; - -if (typeof (JSIL) === "undefined") - throw new Error("JSIL.Core is required"); - -if (!$jsilcore) - throw new Error("JSIL.Core is required"); - -// -// Since alot of operators are shared between Int64 and UInt64, we construct both types using this function -JSIL.Make64BitInt = function ($, _me) { - var mscorlib = JSIL.GetCorlib(); - - function lazy(f) { - var state = null; - return function getLazyValue () { - if (state === null) - state = f(); - return state; - }; - }; - - var me = lazy(_me); - - var ctor = function ctor (a, b, c) { - return new (me())(a, b, c); - }; - - var mktemp = function () { - return lazy(function () { - return ctor(0, 0, 0); - }); - }; - - var maxValue = lazy(function () { - return ctor(0xFFFFFF, 0xFFFFFF, 0xFFFF); - }); - - var zero = lazy(function () { - return ctor(0, 0, 0); - }); - - var one = lazy(function () { - return ctor(1, 0, 0); - }); - - var tempLS = mktemp(); - var tempMul1 = mktemp(); - var tempMul2 = mktemp(); - - var makeOrReturn = function makeOrReturn (result, a, b, c) { - if (result) { - result.a = a & 0xffffff; - result.b = b & 0xffffff; - result.c = c & 0xffff; - return result; - } - - return ctor(a & 0xffffff, b & 0xffffff, c & 0xffff); - }; - - var tryParse = - function xInt64_TryParse (text, style, result) { - var r = zero(); - - var radix = 10; - - if (style & System.Globalization.NumberStyles.AllowHexSpecifier) - radix = 16; - - var rdx = ctor(radix, 0, 0); - var neg = false; - - for (var i = 0; i < text.length; i++) { - if (i == 0 && text[i] == '-') { - neg = true; - continue; - } - var c = parseInt(text[i], radix); - if (isNaN(c)) { - result.set(zero()); - return false; - } - r = me().op_Addition(ctor(c, 0, 0), me().op_Multiplication(rdx, r)); - } - - if (neg) - r = me().op_UnaryNegation(r); - - result.set(r); - - return true; - }; - - $.RawMethod(true, "Create", function xInt64_Create (a, b, c) { - return new (me())(a, b, c); - }); - - $.RawMethod(true, "FromBytes", function xInt64_FromBytes (bytes, offset) { - var a = (bytes[offset + 0] << 0) | - (bytes[offset + 1] << 8) | - (bytes[offset + 2] << 16); - var b = (bytes[offset + 3] << 0) | - (bytes[offset + 4] << 8) | - (bytes[offset + 5] << 16); - var c = (bytes[offset + 6] << 0) | - (bytes[offset + 7] << 8); - return new (me())(a, b, c); - }); - - $.RawMethod(false, ".ctor", function xInt64__ctor (a, b, c) { - this.a = a | 0; - this.b = b | 0; - this.c = c | 0; - }); - - $.Method({ Static: true, Public: true }, "Parse", - (new JSIL.MethodSignature($.Type, ["System.String"], [])), - function xInt64_Parse (text) { - var result = new JSIL.BoxedVariable(null); - if (!tryParse(text, 0, result)) - throw new System.Exception("NumberParseException"); - - return result.get(); - }); - - $.Method({ Static: true, Public: true }, "op_Addition", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_Addition (a, b, result) { - var ca = a.a + b.a; - var ra = (ca & 0xffffff000000) >> 24; - var cb = ra + a.b + b.b; - var rb = (cb & 0xffffff000000) >> 24; - var cc = rb + a.c + b.c; - - return makeOrReturn(result, ca, cb, cc); - }); - - $.Method({ Static: true, Public: true }, "op_Subtraction", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_Subtraction (a, b, result) { - var ca = (a.a - b.a) | 0; - var ra = 0; - if (ca < 0) { - ca = 0x1000000 + ca; - ra = -1; - } - var cb = (ra + ((a.b - b.b) | 0)) | 0; - var rb = 0; - if (cb < 0) { - cb = 0x1000000 + cb; - rb = -1; - } - var cc = (rb + ((a.c - b.c) | 0)) | 0; - if (cc < 0) { - cc = 0x10000 + cc; - } - - return makeOrReturn(result, ca, cb, cc); - }); - - $.Method({ Static: true, Public: true }, "op_LeftShift", - (new JSIL.MethodSignature($.Type, [$.Type, mscorlib.TypeRef("System.Int32")], [])), - function xInt64_op_LeftShift (a, n, result) { // a is UInt64, n is Int32 - if (!result) - result = ctor(0, 0, 0); - - n = n & 0x3f; - - var maxShift = 8; - if (n > 8) { - return me().op_LeftShift(me().op_LeftShift(a, maxShift, tempLS()), n - maxShift, result); - } - - var bat = a.a << n; - var ba = bat & 0xffffff; - var ra = (bat >>> 24) & 0xffffff; - var bbt = (a.b << n) | ra; - var bb = bbt & 0xffffff; - var rb = (bbt >>> 24) & 0xffff; - var bct = a.c << n; - var bc = (bct & 0xffff) | rb; - - return makeOrReturn(result, ba, bb, bc); - }); - - $.Method({ Static: true, Public: true }, "op_OnesComplement", - (new JSIL.MethodSignature($.Type, [$.Type], [])), - function xInt64_op_OnesComplement (a, result) { - return makeOrReturn(result, ~a.a, ~a.b, ~a.c); - }); - - $.Method({ Static: true, Public: true }, "op_ExclusiveOr", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_ExclusiveOr (a, b, result) { - return makeOrReturn(result, a.a ^ b.a, a.b ^ b.b, a.c ^ b.c); - }); - - $.Method({ Static: true, Public: true }, "op_BitwiseAnd", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_BitwiseAnd (a, b, result) { - return makeOrReturn(result, a.a & b.a, a.b & b.b, a.c & b.c); - }); - - $.Method({ Static: true, Public: true }, "op_BitwiseOr", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_BitwiseOr (a, b, result) { - return makeOrReturn(result, a.a | b.a, a.b | b.b, a.c | b.c); - }); - - - $.Method({ Static: true, Public: true }, "op_Equality", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function xInt64_op_Equality (a, b) { - return a.a === b.a && a.b === b.b && a.c === b.c; - }); - - $.Method({ Static: true, Public: true }, "op_Inequality", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function xInt64_op_Inequality (a, b) { - return a.a !== b.a || a.b !== b.b || a.c !== b.c; - }); - - $.Method({ Static: true, Public: true }, "op_Decrement", - (new JSIL.MethodSignature($.Type, [$.Type], [])), - function xInt64_op_Decrement (a, result) { - if (a.a > 0) - return makeOrReturn(result, a.a - 1, a.b, a.c); - else - return me().op_Subtraction(a, one(), result); - }); - - $.Method({ Static: true, Public: true }, "op_Increment", - (new JSIL.MethodSignature($.Type, [$.Type], [])), - function xInt64_op_Increment (a, result) { - if (a.a < 0xffffff) - return makeOrReturn(result, a.a + 1, a.b, a.c); - else - return me().op_Addition(a, one(), result); - }); - - $.Method({ Static: true, Public: true }, "op_Multiplication", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function xInt64_op_Multiplication (a, b, result) { - if (me().op_Equality(a, zero()) || me().op_Equality(b, zero())) - return zero(); - - if (mscorlib.System.UInt64.op_GreaterThan(a, b)) - return me().op_Multiplication(b, a, result); - - var s = result; - if (!s) - s = ctor(0, 0, 0); - - if (a.a & 1 == 1) { - s.a = b.a; - s.b = b.b; - s.c = b.c; - } - - var l = one(); - - while (!me().op_Equality(a, l)) { - a = mscorlib.System.UInt64.op_RightShift(a, 1, tempMul1()); - b = me().op_LeftShift(b, 1, tempMul2()); - - if (a.a & 1 == 1) - s = me().op_Addition(b, s, s); - } - - return s; - }); - - $.RawMethod(true, "CheckType", function xInt64_CheckType (value) { - return value && - (typeof value.a === "number") && - (typeof value.b === "number") && - (typeof value.c === "number"); - }); - - $.RawMethod(false, "valueOf", function xInt64_valueOf () { - return this.ToNumber(); - }); - - $.RawMethod(true, "FromNumberImpl", function (n, makeResult) { - if (n < 0) - JSIL.RuntimeError("cannot construct UInt64 from negative number"); - - var bits24 = 0xffffff; - - var floorN = Math.floor(n); - var n0 = floorN | 0; - var n1 = (floorN / 0x1000000) | 0; - var n2 = (floorN / 0x1000000000000) | 0; - - return makeResult( - (n0 & bits24), - (n1 & bits24), - (n2 & bits24) - ); - }); - - return { - lazy: lazy, - me: me, - ctor: ctor, - mktemp: mktemp - }; -}; - -JSIL.ImplementExternals("System.UInt64", function ($) { - var mscorlib = JSIL.GetCorlib(); - - var locals = JSIL.Make64BitInt($, function () { - return mscorlib.System.UInt64; - }); - var lazy = locals.lazy; - var me = locals.me; - var ctor = locals.ctor; - var mktemp = locals.mktemp; - - var maxValue = lazy(function () { - return ctor(0xFFFFFF, 0xFFFFFF, 0xFFFF); - }); - - var minValue = lazy(function () { - return ctor(0, 0, 0); - }); - - var zero = lazy(function () { - return ctor(0, 0, 0); - }); - - var one = lazy(function () { - return ctor(1, 0, 0); - }); - - var tempRS = mktemp(); - var tempDiv = mktemp(); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_Division", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function UInt64_op_Division (n, d, result) { - var equality = me().op_Equality, - greaterThanOrEqual = me().op_GreaterThanOrEqual, - subtraction = me().op_Subtraction, - leftShift = me().op_LeftShift; - - if (equality(d, minValue())) - throw new Error("System.DivideByZeroException"); - - var q = result; - if (q) - q.a = q.b = q.c = 0; - else - q = ctor(0, 0, 0); - - var r = tempDiv(); - r.a = r.b = r.c = 0; - - for (var i = 63; i >= 0; i--) { - r = leftShift(r, 1, r); - - var li = i < 24 ? 0 : - i < 48 ? 1 : 2; - var lk = i < 24 ? "a" : - i < 48 ? "b" : "c"; - var s = (i - 24 * li); - - r.a |= (n[lk] & (1 << s)) >>> s; - - if (greaterThanOrEqual(r, d)) { - r = subtraction(r, d, r); - q[lk] |= 1 << s; - } - } - - return q; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_Modulus", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function UInt64_op_Modulus (n, d, result) { - var equality = me().op_Equality, - greaterThanOrEqual = me().op_GreaterThanOrEqual, - subtraction = me().op_Subtraction, - leftShift = me().op_LeftShift; - - if (equality(d, minValue())) - throw new Error("System.DivideByZeroException"); - - var r = result || ctor(0, 0, 0); - r.a = r.b = r.c = 0; - - for (var i = 63; i >= 0; i--) { - r = leftShift(r, 1, r); - - var li = i < 24 ? 0 : - i < 48 ? 1 : 2; - var lk = i < 24 ? "a" : - i < 48 ? "b" : "c"; - var s = (i - 24 * li); - - r.a |= (n[lk] & (1 << s)) >>> s; - - if (greaterThanOrEqual(r, d)) { - r = subtraction(r, d, r); - } - } - - return r; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_RightShift", - (new JSIL.MethodSignature($.Type, [$.Type, mscorlib.TypeRef("System.Int32")], [])), - function UInt64_op_RightShift (a, n, result) { - - n = n & 0x3f; - - if (n > 24) { - return mscorlib.System.UInt64.op_RightShift( - mscorlib.System.UInt64.op_RightShift(a, 24, tempRS()), n - 24, result - ); - } - - var m = (1 << n) - 1; - var cr = (a.c & m) << (24 - n); - var ct = a.c >>> n; - var br = (a.b & m) << (24 - n); - var bt = a.b >>> n; - var at = a.a >>> n; - - if (!result) { - result = ctor(at | br, bt | cr, ct); - } else { - result.a = at | br; - result.b = bt | cr; - result.c = ct; - } - - return result; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_LessThan", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function UInt64_op_LessThan (a, b) { - var adiff = a.c - b.c; - if (adiff < 0) - return true; - - if (adiff > 0) - return false; - - var bdiff = a.b - b.b; - if (bdiff < 0) - return true; - - if (bdiff > 0) - return false; - - return a.a < b.a; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_LessThanOrEqual", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function UInt64_op_LessThanOrEqual (a, b) { - var adiff = a.c - b.c; - if (adiff < 0) - return true; - - if (adiff > 0) - return false; - - var bdiff = a.b - b.b; - if (bdiff < 0) - return true; - - if (bdiff > 0) - return false; - - return a.a <= b.a; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_GreaterThan", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function UInt64_op_GreaterThan (a, b) { - var adiff = a.c - b.c; - if (adiff > 0) - return true; - - if (adiff < 0) - return false; - - var bdiff = a.b - b.b; - if (bdiff > 0) - return true; - - if (bdiff < 0) - return false; - - return a.a > b.a; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_GreaterThanOrEqual", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function UInt64_op_GreaterThanOrEqual (a, b) { - var adiff = a.c - b.c; - if (adiff > 0) - return true; - - if (adiff < 0) - return false; - - var bdiff = a.b - b.b; - if (bdiff > 0) - return true; - - if (bdiff < 0) - return false; - - return a.a >= b.a; - }); - - $.Method({ Static: false, Public: true }, "toString", - new JSIL.MethodSignature("System.String", []), - function UInt64_toString () { - var a = this; - var ten = me().FromNumber(10); - - var s = ""; - - do { - var r = me().op_Modulus(a, ten); - s = r.a.toString() + s; - a = me().op_Division(a, ten); - } while (me().op_GreaterThan(a, minValue())); - - return s; - }); - - $.Method({ Static: false, Public: true }, "ToString", - new JSIL.MethodSignature("System.String", []), - function UInt64_ToString () { - return this.toString(); - } - ); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToHex", - new JSIL.MethodSignature("System.String", []), - function UInt64_ToHex () { - var s = this.a.toString(16); - - if (this.b > 0 || this.c > 0) { - if (s.length < 6) - s = (new Array(6 - s.length + 1)).join('0') + s; - - s = this.b.toString(16) + s; - - if (this.c > 0) { - if (s.length < 12) - s = (new Array(12 - s.length + 1)).join('0') + s; - - s = this.c.toString(16) + s; - } - } - - return s; - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToInt64", - new JSIL.MethodSignature(mscorlib.TypeRef("System.Int64"), []), - function UInt64_ToInt64 () { - return new mscorlib.System.Int64(this.a, this.b, this.c); - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "Clone", - new JSIL.MethodSignature($.Type, []), - function UInt64_Clone () { - return ctor(this.a, this.b, this.c); - }); - - $.Method({ Static: false, Public: true }, "Object.Equals", - new JSIL.MethodSignature(System.Boolean, [System.Object]), - function UInt64_Equals (rhs) { - return UInt64.op_Equality(this, rhs); - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: false }, "FromInt32", - (new JSIL.MethodSignature($.Type, [$.Int32], [])), - function UInt64_FromInt32 (n) { - if (n < 0) - JSIL.RuntimeError("cannot construct UInt64 from negative number"); - - // only using 48 bits - - var n0 = Math.floor(n); - return ctor( - (n0 & 0xffffff), - (n0 >>> 24) & 0xffffff, - 0); - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: false }, "FromNumber", - (new JSIL.MethodSignature($.Type, [$.Double], [])), - function UInt64_FromNumber (n) { - return me().FromNumberImpl(n, ctor); - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToUInt32", - (new JSIL.MethodSignature($.UInt32, [], [])), - function UInt64_FromUInt32 () { - return ((0x1000000 * this.b) + this.a) >>> 0; - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToNumber", - (new JSIL.MethodSignature($.Double, [], [])), - function UInt64_ToNumber(maxValue, signed) { - if (arguments.length === 0 || maxValue == -1) - return 0x1000000 * (0x1000000 * this.c + this.b) + this.a; - - var truncated = me() - .op_BitwiseAnd(this, me().FromNumber(maxValue)) - .ToNumber(); - - if (signed) { - var maxPlusOne = maxValue + 1; - var signedMaxValue = maxValue >>> 1; - if (truncated > signedMaxValue) - return truncated - signedMaxValue; - else - return truncated; - } - else { - return truncated; - } - }); - - $.Method({ Static: false, Public: true }, "GetHashCode", - (new JSIL.MethodSignature($.Int32, [], [])), - function UInt64_GetHashCode () { - return this.a | ((this.b & 0xff) << 24); - }); -}); - -JSIL.ImplementExternals("System.Int64", function ($) { - - // The unsigned range 0 to 0x7FFFFFFFFFFFFFFF (= Int64.MaxValue) is positive: 0 to 9223372036854775807 - // The directly following unsigned range 0x8000000000000000 (= Int64.MaxValue + 1 = Int64.MinValue) to 0xFFFFFFFFFFFFFFFF is negative: -9223372036854775808 to -1 - // - // signed value - // ^ - // | / - // | / - // | / - // |/z - // ------------------> unsigned value - // | / - // | / - // | / - // | / - // - - var mscorlib = JSIL.GetCorlib(); - - var locals = JSIL.Make64BitInt($, function () { - return mscorlib.System.Int64; - }); - var lazy = locals.lazy; - var me = locals.me; - var ctor = locals.ctor; - var mktemp = locals.mktemp; - - var zero = lazy(function () { - return ctor(0, 0, 0); - }); - - var one = lazy(function () { - return ctor(1, 0, 0); - }); - - var minusOne = lazy(function () { - return ctor(0xFFFFFF, 0xFFFFFF, 0xFFFF); - }); - - var signedMaxValue = lazy(function () { - return ctor(0xFFFFFF, 0xFFFFFF, 0x7FFF); - }); - - var unsignedMaxValue = lazy(function () { - return ctor(0xFFFFFF, 0xFFFFFF, 0xFFFF); - }); - - var tempRS = mktemp(); - var tempRS1 = mktemp(); - var tempRS2 = mktemp(); - var tempRS3 = mktemp(); - - var tempTS = mktemp(); - var tempDiv = mktemp(); - var tempDiv2 = mktemp(); - var tempDiv3 = mktemp(); - var tempDiv4 = mktemp(); - var tempMod = mktemp(); - var tempMod2 = mktemp(); - var tempMod3 = mktemp(); - var tempMod4 = mktemp(); - var tempN = mktemp(); - - var isNegative = function Int64_IsNegative (a) { - return mscorlib.System.UInt64.op_GreaterThan(a, signedMaxValue()); - }; - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_UnaryNegation", - (new JSIL.MethodSignature($.Type, [$.Type], [])), - function Int64_op_UnaryNegation (a, result) { - var complement = me().op_Subtraction(unsignedMaxValue(), a, tempN()); - return me().op_Addition(complement, one(), result); - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_Division", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function Int64_op_Division (n, d, result) { - if (me().op_Equality(d, zero())) - throw new Error("System.DivideByZeroException"); - - if (!result) - result = ctor(0, 0, 0); - else - result.a = result.b = result.c = 0; - - if (isNegative(d)) - return me().op_Division( - me().op_UnaryNegation(n, tempDiv()), me().op_UnaryNegation(d, tempDiv2()), result - ); - else if (isNegative(n)) - return me().op_UnaryNegation( - me().op_Division( - me().op_UnaryNegation(n, tempDiv3()), d, tempDiv4() - ), result - ); - else - return mscorlib.System.UInt64.op_Division(n, d, result); - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_Modulus", - (new JSIL.MethodSignature($.Type, [$.Type, $.Type], [])), - function Int64_op_Modulus (n, d, result) { - if (me().op_Equality(d, zero())) - throw new Error("System.DivideByZeroException"); - - if (!result) - result = ctor(0, 0, 0); - - if (isNegative(d)) - return me().op_Modulus( - me().op_UnaryNegation(n, tempMod()), me().op_UnaryNegation(d, tempMod2()), result - ); - else if (isNegative(n)) - return me().op_UnaryNegation( - me().op_Modulus( - me().op_UnaryNegation(n, tempMod3()), d, tempMod4() - ), result - ); - else - // fix return type error - return mscorlib.System.UInt64.op_Modulus(n, d, result); - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_RightShift", - (new JSIL.MethodSignature($.Type, [$.Type, mscorlib.TypeRef("System.Int32")], [])), - function Int64_op_RightShift (a, n, result) { - // Int64 (signed) uses arithmetic shift, UIn64 (unsigned) uses logical shift - if (!result) - result = ctor(0, 0, 0); - - if (n === 0) { - var result2 = a; - } else if (n > 32) { - result2 = me().op_RightShift(me().op_RightShift(a, 32), n - 32); - } else { - var unsignedShift = mscorlib.System.UInt64.op_RightShift(a, n); - - if (isNegative(a)) { - var outshift = mscorlib.System.UInt64.op_RightShift(mscorlib.System.UInt64.Create(16777215, 16777215, 65535), n); - var inshift = mscorlib.System.UInt64.op_LeftShift(outshift, 64 - n); - var uresult = mscorlib.System.UInt64.op_BitwiseOr(unsignedShift, inshift); - } else { - uresult = unsignedShift; - } - result2 = (uresult).ToInt64(); - } - return result2; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_GreaterThan", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function Int64_op_GreaterThan (a, b) { - var an = isNegative(a); - var bn = isNegative(b); - - if (an === bn) - return mscorlib.System.UInt64.op_GreaterThan(a, b); - else - return bn; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_GreaterThanOrEqual", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function Int64_op_GreaterThanOrEqual (a, b) { - var an = isNegative(a); - var bn = isNegative(b); - - if (an === bn) - return mscorlib.System.UInt64.op_GreaterThanOrEqual(a, b); - else - return bn; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_LessThan", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function Int64_op_LessThan (a, b) { - var an = isNegative(a); - var bn = isNegative(b); - - if (an === bn) - return mscorlib.System.UInt64.op_LessThan(a, b); - else - return an; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: true }, "op_LessThanOrEqual", - (new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), [$.Type, $.Type], [])), - function Int64_op_LessThanOrEqual (a, b) { - var an = isNegative(a); - var bn = isNegative(b); - - if (an === bn) - return mscorlib.System.UInt64.op_LessThanOrEqual(a, b); - else - return an; - }); - - // Might need to be implemented externally - $.Method({ Static: false, Public: true }, "Equals", - new JSIL.MethodSignature(mscorlib.TypeRef("System.Boolean"), []), - function Int64_Equals (a) { - return me().op_Equality(this, a); - }); - - // Might need to be implemented externally - $.Method({ Static: false, Public: true }, "toString", - new JSIL.MethodSignature("System.String", []), - function Int64_toString () { - var s = ""; - var a = this; - if (isNegative(this)) { - s += "-"; - a = me().op_UnaryNegation(this, tempTS()); - } - s += mscorlib.System.UInt64.prototype.toString.apply(a); - return s; - }); - - $.Method({ Static: false, Public: true }, "ToString", - new JSIL.MethodSignature("System.String", []), - function Int64_ToString () { - return this.toString(); - } - ); - - // Not present in mscorlib - $.Method({ Static: true, Public: false }, "FromInt32", - (new JSIL.MethodSignature($.Type, [$.Int32], [])), - function Int64_FromInt32 (n) { - var sign = n < 0 ? -1 : 1; - n = Math.abs(n); - - var n0 = Math.floor(n); - var r = ctor(n0 & 0xffffff, (n0 >>> 24) & 0xffffff, 0); - - if (sign == -1) - return me().op_UnaryNegation(r); - else - return r; - }); - - // Not present in mscorlib - $.Method({ Static: true, Public: false }, "FromNumber", - (new JSIL.MethodSignature($.Type, [$.Double], [])), - function Int64_FromNumber (n) { - var sign = n < 0 ? -1 : 1; - var r = me().FromNumberImpl(Math.abs(n), ctor); - - if (sign == -1) - return me().op_UnaryNegation(r, r); - else - return r; - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToUInt64", - new JSIL.MethodSignature($.UInt64, []), - function Int64_ToUInt64 () { - return new mscorlib.System.UInt64(this.a, this.b, this.c); - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToInt32", - (new JSIL.MethodSignature($.Int32, [], [])), - function Int64_ToInt32 () { - var neg = isNegative(this); - var n = neg ? me().op_UnaryNegation(this) : this; - var r = (0x1000000 * (n.b) + n.a) >>> 0; - - if (neg) - return -r; - else - return r; - }); - - $.Method({ Static: false, Public: true }, "GetHashCode", - (new JSIL.MethodSignature($.Int32, [], [])), - function Int64_GetHashCode () { - return this.a | ((this.b & 0xff) << 24); - }); - - // Not present in mscorlib - $.Method({ Static: false, Public: true }, "ToNumber", - (new JSIL.MethodSignature($.Double, [], [])), - function Int64_ToNumber (maxValue, signed) { - if (arguments.length === 0 || maxValue == -1) { - var neg = isNegative(this); - var n = neg ? me().op_UnaryNegation(this) : this; - var r = 0x1000000 * (0x1000000 * n.c + n.b) + n.a; - - if (neg) - return -r; - else - return r; - } - - var truncated = me() - .op_BitwiseAnd(this, me().FromNumber(maxValue)) - .ToNumber(); - - if (signed) { - var signedMaxValue = maxValue >>> 1; - if (truncated > signedMaxValue) - return (truncated - maxValue) - 1; - else - return truncated; - } - else { - return truncated; - } - }); -}); - -JSIL.MakeStruct("System.ValueType", "System.UInt64", true, [], function ($) { - $.Field({ Static: false, Public: false}, "a", $.Int32); - $.Field({ Static: false, Public: false}, "b", $.Int32); - $.Field({ Static: false, Public: false}, "c", $.Int32); - - JSIL.MakeCastMethods( - $.publicInterface, $.typeObject, "int64" - ); -}); - -JSIL.MakeStruct("System.ValueType", "System.Int64", true, [], function ($) { - $.Field({ Static: false, Public: false}, "a", $.Int32); - $.Field({ Static: false, Public: false}, "b", $.Int32); - $.Field({ Static: false, Public: false}, "c", $.Int32); - - JSIL.MakeCastMethods( - $.publicInterface, $.typeObject, "int64" - ); -}); +//? __out.GENERATE_STUBS=true; +//? include("../Includes/Bootstrap/Int/Main.js"); \ No newline at end of file diff --git a/JSIL.Libraries/Sources/JSIL.Core.js b/JSIL.Libraries/Sources/JSIL.Core.js index e2722fb70..cf1bec744 100644 --- a/JSIL.Libraries/Sources/JSIL.Core.js +++ b/JSIL.Libraries/Sources/JSIL.Core.js @@ -2106,6 +2106,20 @@ JSIL.MakeNumericType = function (baseType, typeName, isIntegral, typedArrayName) return (value | 0); } ); + + var $formatSignature = function () { + return ($formatSignature = JSIL.Memoize(new JSIL.MethodSignature($jsilcore.TypeRef("System.String"), [ + $jsilcore.TypeRef("System.String"), $jsilcore.TypeRef(typeName), + $jsilcore.TypeRef("System.IFormatProvider") + ])))(); + }; + + $.RawMethod( + true, "$ToString", + function $ToString(self, format, formatProvider) { + return $formatSignature().CallStatic($jsilcore.JSIL.System.NumberFormatter, "NumberToString", null, format, self, formatProvider).toString(); + } + ); }); }; diff --git a/JSIL.Libraries/Sources/JSIL.js b/JSIL.Libraries/Sources/JSIL.js index aa0548c39..19dfc9213 100644 --- a/JSIL.Libraries/Sources/JSIL.js +++ b/JSIL.Libraries/Sources/JSIL.js @@ -278,7 +278,8 @@ var $jsilloaderstate = { } else { environment.loadScript(libraryRoot + "IgnoredBCL/JSIL.Bootstrap.js"); } - + + environment.loadScript(libraryRoot + "JSIL.mscorlib.js"); environment.loadScript(libraryRoot + "JSIL.Bootstrap.Int64.js"); environment.loadScript(libraryRoot + "JSIL.Bootstrap.DateTime.js"); environment.loadScript(libraryRoot + "JSIL.Bootstrap.Text.js"); diff --git a/JSIL.Libraries/Targets/MSBuild.JSIL.targets b/JSIL.Libraries/Targets/MSBuild.JSIL.targets new file mode 100644 index 000000000..49a9de9f5 --- /dev/null +++ b/JSIL.Libraries/Targets/MSBuild.JSIL.targets @@ -0,0 +1,18 @@ + + + + + $(OutDir)JSILc.AnyCPU.exe + "$(JsilPath)" + mono "$(JsilPath)" + + + + + + + + + diff --git a/JSIL.Libraries/gulpfile.js b/JSIL.Libraries/gulpfile.js index eff72ef03..d8a5dfcf7 100644 --- a/JSIL.Libraries/gulpfile.js +++ b/JSIL.Libraries/gulpfile.js @@ -8,7 +8,7 @@ var eol = require('gulp-eol'); var header = "/* It is auto-generated file. Do not modify it. */"; gulp.task('metascript', ['clean'], function () { - return gulp.src('Sources/**/*.js') + return gulp.src(['Sources/**/*.js', 'Generated/**/*.js']) .pipe(metascriptPipe()) .pipe(replace(/^\uFEFF/gm, '')) // remove BOM from file internal parts .pipe(replace(/(.)/, '\uFEFF' + header + '\n$1')) // add BOM with header diff --git a/JSIL.mscorlib/Imports.cs b/JSIL.mscorlib/Imports.cs new file mode 100644 index 000000000..db3305c7d --- /dev/null +++ b/JSIL.mscorlib/Imports.cs @@ -0,0 +1,19 @@ +namespace JSIL.mscorlib +{ + using global::System; + using global::System.Globalization; + using JSIL.Meta; + using JSIL.Proxy; + + [JSProxy(typeof(NumberFormatInfo))] + [JSImportType] + class NumberFormatInfoImport + { + } + + [JSProxy(typeof(ICloneable))] + [JSImportType] + interface ICloneableImport + { + } +} diff --git a/JSIL.mscorlib/JSIL.mscorlib.csproj b/JSIL.mscorlib/JSIL.mscorlib.csproj new file mode 100644 index 000000000..3e44b6dcd --- /dev/null +++ b/JSIL.mscorlib/JSIL.mscorlib.csproj @@ -0,0 +1,77 @@ + + + + + Debug + AnyCPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7} + Library + Properties + JSIL.mscorlib + JSIL.mscorlib + v4.5 + 512 + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + {c7bf4561-20dd-4e49-8b5a-4e8af032c47a} + Compiler + + + {37c67c73-1f58-49b8-a39e-768ac88c2447} + Meta + + + {12dbcc9a-50fe-43b1-bad1-8029d4ad60c9} + Proxies.4.0 + + + + + PreserveNewest + + + + + + \ No newline at end of file diff --git a/JSIL.mscorlib/JSIL.mscorlib.dll.jsilconfig b/JSIL.mscorlib/JSIL.mscorlib.dll.jsilconfig new file mode 100644 index 000000000..5637d63a3 --- /dev/null +++ b/JSIL.mscorlib/JSIL.mscorlib.dll.jsilconfig @@ -0,0 +1,6 @@ +{ + "OutputFileName": "../../JSIL.Libraries/Generated/JSIL.mscorlib.js", + "OutputDirectory": "%AssemblyDirectory%", + "IncludeDependencies": false, + "MonoFixConfig" : {} +} \ No newline at end of file diff --git a/JSIL.mscorlib/JSIL/System/NumberFormatter.Data.cs b/JSIL.mscorlib/JSIL/System/NumberFormatter.Data.cs new file mode 100644 index 000000000..0f778b39b --- /dev/null +++ b/JSIL.mscorlib/JSIL/System/NumberFormatter.Data.cs @@ -0,0 +1,918 @@ +// +// mono/metadata/number-formatter.h +// originally ported from Grassshopper +// MIT/X11 licanse granted by Eyal Alaluf +// + +namespace JSIL.System +{ + sealed partial class NumberFormatter + { + private static void GetFormatterTables(out ulong[] MantissaBitsTable, out int[] TensExponentTable, + out char[] DigitLowerTable, out char[] DigitUpperTable, + out long[] TenPowersList, out int[] DecHexDigits) + { + MantissaBitsTable = new[] + { + 4556951262222748432UL, 9113902524445496865UL, 1822780504889099373UL, + 3645561009778198746UL, 7291122019556397492UL, 14582244039112794984UL, + 2916448807822558996UL, 5832897615645117993UL, 11665795231290235987UL, + 2333159046258047197UL, 4666318092516094394UL, 9332636185032188789UL, + 1866527237006437757UL, 3733054474012875515UL, 7466108948025751031UL, + 14932217896051502063UL, 2986443579210300412UL, 5972887158420600825UL, + 11945774316841201651UL, 2389154863368240330UL, 4778309726736480660UL, + 9556619453472961320UL, 1911323890694592264UL, 3822647781389184528UL, + 7645295562778369056UL, 15290591125556738113UL, 3058118225111347622UL, + 6116236450222695245UL, 12232472900445390490UL, 2446494580089078098UL, + 4892989160178156196UL, 9785978320356312392UL, 1957195664071262478UL, + 3914391328142524957UL, 7828782656285049914UL, 15657565312570099828UL, + 3131513062514019965UL, 6263026125028039931UL, 12526052250056079862UL, + 2505210450011215972UL, 5010420900022431944UL, 10020841800044863889UL, + 2004168360008972777UL, 4008336720017945555UL, 8016673440035891111UL, + 16033346880071782223UL, 3206669376014356444UL, 6413338752028712889UL, + 12826677504057425779UL, 2565335500811485155UL, 5130671001622970311UL, + 10261342003245940623UL, 2052268400649188124UL, 4104536801298376249UL, + 8209073602596752498UL, 16418147205193504997UL, 3283629441038700999UL, + 6567258882077401998UL, 13134517764154803997UL, 2626903552830960799UL, + 5253807105661921599UL, 10507614211323843198UL, 2101522842264768639UL, + 4203045684529537279UL, 8406091369059074558UL, 16812182738118149117UL, + 3362436547623629823UL, 6724873095247259646UL, 13449746190494519293UL, + 2689949238098903858UL, 5379898476197807717UL, 10759796952395615435UL, + 2151959390479123087UL, 4303918780958246174UL, 8607837561916492348UL, + 17215675123832984696UL, 3443135024766596939UL, 6886270049533193878UL, + 13772540099066387756UL, 2754508019813277551UL, 5509016039626555102UL, + 11018032079253110205UL, 2203606415850622041UL, 4407212831701244082UL, + 8814425663402488164UL, 17628851326804976328UL, 3525770265360995265UL, + 7051540530721990531UL, 14103081061443981063UL, 2820616212288796212UL, + 5641232424577592425UL, 11282464849155184850UL, 2256492969831036970UL, + 4512985939662073940UL, 9025971879324147880UL, 18051943758648295760UL, + 3610388751729659152UL, 7220777503459318304UL, 14441555006918636608UL, + 2888311001383727321UL, 5776622002767454643UL, 11553244005534909286UL, + 2310648801106981857UL, 4621297602213963714UL, 9242595204427927429UL, + 1848519040885585485UL, 3697038081771170971UL, 7394076163542341943UL, + 14788152327084683887UL, 2957630465416936777UL, 5915260930833873554UL, + 11830521861667747109UL, 2366104372333549421UL, 4732208744667098843UL, + 9464417489334197687UL, 1892883497866839537UL, 3785766995733679075UL, + 7571533991467358150UL, 15143067982934716300UL, 3028613596586943260UL, + 6057227193173886520UL, 12114454386347773040UL, 2422890877269554608UL, + 4845781754539109216UL, 9691563509078218432UL, 1938312701815643686UL, + 3876625403631287372UL, 7753250807262574745UL, 15506501614525149491UL, + 3101300322905029898UL, 6202600645810059796UL, 12405201291620119593UL, + 2481040258324023918UL, 4962080516648047837UL, 9924161033296095674UL, + 1984832206659219134UL, 3969664413318438269UL, 7939328826636876539UL, + 15878657653273753079UL, 3175731530654750615UL, 6351463061309501231UL, + 12702926122619002463UL, 2540585224523800492UL, 5081170449047600985UL, + 10162340898095201970UL, 2032468179619040394UL, 4064936359238080788UL, + 8129872718476161576UL, 16259745436952323153UL, 3251949087390464630UL, + 6503898174780929261UL, 13007796349561858522UL, 2601559269912371704UL, + 5203118539824743409UL, 10406237079649486818UL, 2081247415929897363UL, + 4162494831859794727UL, 8324989663719589454UL, 16649979327439178909UL, + 3329995865487835781UL, 6659991730975671563UL, 13319983461951343127UL, + 2663996692390268625UL, 5327993384780537250UL, 10655986769561074501UL, + 2131197353912214900UL, 4262394707824429800UL, 8524789415648859601UL, + 17049578831297719202UL, 3409915766259543840UL, 6819831532519087681UL, + 13639663065038175362UL, 2727932613007635072UL, 5455865226015270144UL, + 10911730452030540289UL, 2182346090406108057UL, 4364692180812216115UL, + 8729384361624432231UL, 17458768723248864463UL, 3491753744649772892UL, + 6983507489299545785UL, 13967014978599091570UL, 2793402995719818314UL, + 5586805991439636628UL, 11173611982879273256UL, 2234722396575854651UL, + 4469444793151709302UL, 8938889586303418605UL, 17877779172606837210UL, + 3575555834521367442UL, 7151111669042734884UL, 14302223338085469768UL, + 2860444667617093953UL, 5720889335234187907UL, 11441778670468375814UL, + 2288355734093675162UL, 4576711468187350325UL, 9153422936374700651UL, + 1830684587274940130UL, 3661369174549880260UL, 7322738349099760521UL, + 14645476698199521043UL, 2929095339639904208UL, 5858190679279808417UL, + 11716381358559616834UL, 2343276271711923366UL, 4686552543423846733UL, + 9373105086847693467UL, 1874621017369538693UL, 3749242034739077387UL, + 7498484069478154774UL, 14996968138956309548UL, 2999393627791261909UL, + 5998787255582523819UL, 11997574511165047638UL, 2399514902233009527UL, + 4799029804466019055UL, 9598059608932038110UL, 1919611921786407622UL, + 3839223843572815244UL, 7678447687145630488UL, 15356895374291260977UL, + 3071379074858252195UL, 6142758149716504390UL, 12285516299433008781UL, + 2457103259886601756UL, 4914206519773203512UL, 9828413039546407025UL, + 1965682607909281405UL, 3931365215818562810UL, 7862730431637125620UL, + 15725460863274251240UL, 3145092172654850248UL, 6290184345309700496UL, + 12580368690619400992UL, 2516073738123880198UL, 5032147476247760397UL, + 10064294952495520794UL, 2012858990499104158UL, 4025717980998208317UL, + 8051435961996416635UL, 16102871923992833270UL, 3220574384798566654UL, + 6441148769597133308UL, 12882297539194266616UL, 2576459507838853323UL, + 5152919015677706646UL, 10305838031355413293UL, 2061167606271082658UL, + 4122335212542165317UL, 8244670425084330634UL, 16489340850168661269UL, + 3297868170033732253UL, 6595736340067464507UL, 13191472680134929015UL, + 2638294536026985803UL, 5276589072053971606UL, 10553178144107943212UL, + 2110635628821588642UL, 4221271257643177284UL, 8442542515286354569UL, + 16885085030572709139UL, 3377017006114541827UL, 6754034012229083655UL, + 13508068024458167311UL, 2701613604891633462UL, 5403227209783266924UL, + 10806454419566533849UL, 2161290883913306769UL, 4322581767826613539UL, + 8645163535653227079UL, 17290327071306454158UL, 3458065414261290831UL, + 6916130828522581663UL, 13832261657045163327UL, 2766452331409032665UL, + 5532904662818065330UL, 11065809325636130661UL, 2213161865127226132UL, + 4426323730254452264UL, 8852647460508904529UL, 17705294921017809058UL, + 3541058984203561811UL, 7082117968407123623UL, 14164235936814247246UL, + 2832847187362849449UL, 5665694374725698898UL, 11331388749451397797UL, + 2266277749890279559UL, 4532555499780559119UL, 9065110999561118238UL, + 1813022199912223647UL, 3626044399824447295UL, 7252088799648894590UL, + 14504177599297789180UL, 2900835519859557836UL, 5801671039719115672UL, + 11603342079438231344UL, 2320668415887646268UL, 4641336831775292537UL, + 9282673663550585075UL, 1856534732710117015UL, 3713069465420234030UL, + 7426138930840468060UL, 14852277861680936121UL, 2970455572336187224UL, + 5940911144672374448UL, 11881822289344748896UL, 2376364457868949779UL, + 4752728915737899558UL, 9505457831475799117UL, 1901091566295159823UL, + 3802183132590319647UL, 7604366265180639294UL, 15208732530361278588UL, + 3041746506072255717UL, 6083493012144511435UL, 12166986024289022870UL, + 2433397204857804574UL, 4866794409715609148UL, 9733588819431218296UL, + 1946717763886243659UL, 3893435527772487318UL, 7786871055544974637UL, + 15573742111089949274UL, 3114748422217989854UL, 6229496844435979709UL, + 12458993688871959419UL, 2491798737774391883UL, 4983597475548783767UL, + 9967194951097567535UL, 1993438990219513507UL, 3986877980439027014UL, + 7973755960878054028UL, 15947511921756108056UL, 3189502384351221611UL, + 6379004768702443222UL, 12758009537404886445UL, 2551601907480977289UL, + 5103203814961954578UL, 10206407629923909156UL, 2041281525984781831UL, + 4082563051969563662UL, 8165126103939127325UL, 16330252207878254650UL, + 3266050441575650930UL, 6532100883151301860UL, 13064201766302603720UL, + 2612840353260520744UL, 5225680706521041488UL, 10451361413042082976UL, + 2090272282608416595UL, 4180544565216833190UL, 8361089130433666380UL, + 16722178260867332761UL, 3344435652173466552UL, 6688871304346933104UL, + 13377742608693866209UL, 2675548521738773241UL, 5351097043477546483UL, + 10702194086955092967UL, 2140438817391018593UL, 4280877634782037187UL, + 8561755269564074374UL, 17123510539128148748UL, 3424702107825629749UL, + 6849404215651259499UL, 13698808431302518998UL, 2739761686260503799UL, + 5479523372521007599UL, 10959046745042015198UL, 2191809349008403039UL, + 4383618698016806079UL, 8767237396033612159UL, 17534474792067224318UL, + 3506894958413444863UL, 7013789916826889727UL, 14027579833653779454UL, + 2805515966730755890UL, 5611031933461511781UL, 11222063866923023563UL, + 2244412773384604712UL, 4488825546769209425UL, 8977651093538418850UL, + 17955302187076837701UL, 3591060437415367540UL, 7182120874830735080UL, + 14364241749661470161UL, 2872848349932294032UL, 5745696699864588064UL, + 11491393399729176129UL, 2298278679945835225UL, 4596557359891670451UL, + 9193114719783340903UL, 1838622943956668180UL, 3677245887913336361UL, + 7354491775826672722UL, 14708983551653345445UL, 2941796710330669089UL, + 5883593420661338178UL, 11767186841322676356UL, 2353437368264535271UL, + 4706874736529070542UL, 9413749473058141084UL, 1882749894611628216UL, + 3765499789223256433UL, 7530999578446512867UL, 15061999156893025735UL, + 3012399831378605147UL, 6024799662757210294UL, 12049599325514420588UL, + 2409919865102884117UL, 4819839730205768235UL, 9639679460411536470UL, + 1927935892082307294UL, 3855871784164614588UL, 7711743568329229176UL, + 15423487136658458353UL, 3084697427331691670UL, 6169394854663383341UL, + 12338789709326766682UL, 2467757941865353336UL, 4935515883730706673UL, + 9871031767461413346UL, 1974206353492282669UL, 3948412706984565338UL, + 7896825413969130677UL, 15793650827938261354UL, 3158730165587652270UL, + 6317460331175304541UL, 12634920662350609083UL, 2526984132470121816UL, + 5053968264940243633UL, 10107936529880487266UL, 2021587305976097453UL, + 4043174611952194906UL, 8086349223904389813UL, 16172698447808779626UL, + 3234539689561755925UL, 6469079379123511850UL, 12938158758247023701UL, + 2587631751649404740UL, 5175263503298809480UL, 10350527006597618960UL, + 2070105401319523792UL, 4140210802639047584UL, 8280421605278095168UL, + 16560843210556190337UL, 3312168642111238067UL, 6624337284222476135UL, + 13248674568444952270UL, 2649734913688990454UL, 5299469827377980908UL, + 10598939654755961816UL, 2119787930951192363UL, 4239575861902384726UL, + 8479151723804769452UL, 16958303447609538905UL, 3391660689521907781UL, + 6783321379043815562UL, 13566642758087631124UL, 2713328551617526224UL, + 5426657103235052449UL, 10853314206470104899UL, 2170662841294020979UL, + 4341325682588041959UL, 8682651365176083919UL, 17365302730352167839UL, + 3473060546070433567UL, 6946121092140867135UL, 13892242184281734271UL, + 2778448436856346854UL, 5556896873712693708UL, 11113793747425387417UL, + 2222758749485077483UL, 4445517498970154966UL, 8891034997940309933UL, + 17782069995880619867UL, 3556413999176123973UL, 7112827998352247947UL, + 14225655996704495894UL, 2845131199340899178UL, 5690262398681798357UL, + 11380524797363596715UL, 2276104959472719343UL, 4552209918945438686UL, + 9104419837890877372UL, 1820883967578175474UL, 3641767935156350948UL, + 7283535870312701897UL, 14567071740625403795UL, 2913414348125080759UL, + 5826828696250161518UL, 11653657392500323036UL, 2330731478500064607UL, + 4661462957000129214UL, 9322925914000258429UL, 1864585182800051685UL, + 3729170365600103371UL, 7458340731200206743UL, 14916681462400413486UL, + 2983336292480082697UL, 5966672584960165394UL, 11933345169920330789UL, + 2386669033984066157UL, 4773338067968132315UL, 9546676135936264631UL, + 1909335227187252926UL, 3818670454374505852UL, 7637340908749011705UL, + 15274681817498023410UL, 3054936363499604682UL, 6109872726999209364UL, + 12219745453998418728UL, 2443949090799683745UL, 4887898181599367491UL, + 9775796363198734982UL, 1955159272639746996UL, 3910318545279493993UL, + 7820637090558987986UL, 15641274181117975972UL, 3128254836223595194UL, + 6256509672447190388UL, 12513019344894380777UL, 2502603868978876155UL, + 5005207737957752311UL, 10010415475915504622UL, 2002083095183100924UL, + 4004166190366201848UL, 8008332380732403697UL, 16016664761464807395UL, + 3203332952292961479UL, 6406665904585922958UL, 12813331809171845916UL, + 2562666361834369183UL, 5125332723668738366UL, 10250665447337476733UL, + 2050133089467495346UL, 4100266178934990693UL, 8200532357869981386UL, + 16401064715739962772UL, 3280212943147992554UL, 6560425886295985109UL, + 13120851772591970218UL, 2624170354518394043UL, 5248340709036788087UL, + 10496681418073576174UL, 2099336283614715234UL, 4198672567229430469UL, + 8397345134458860939UL, 16794690268917721879UL, 3358938053783544375UL, + 6717876107567088751UL, 13435752215134177503UL, 2687150443026835500UL, + 5374300886053671001UL, 10748601772107342002UL, 2149720354421468400UL, + 4299440708842936801UL, 8598881417685873602UL, 17197762835371747204UL, + 3439552567074349440UL, 6879105134148698881UL, 13758210268297397763UL, + 2751642053659479552UL, 5503284107318959105UL, 11006568214637918210UL, + 2201313642927583642UL, 4402627285855167284UL, 8805254571710334568UL, + 17610509143420669137UL, 3522101828684133827UL, 7044203657368267654UL, + 14088407314736535309UL, 2817681462947307061UL, 5635362925894614123UL, + 11270725851789228247UL, 2254145170357845649UL, 4508290340715691299UL, + 9016580681431382598UL, 18033161362862765196UL, 3606632272572553039UL, + 7213264545145106078UL, 14426529090290212157UL, 2885305818058042431UL, + 5770611636116084862UL, 11541223272232169725UL, 2308244654446433945UL, + 4616489308892867890UL, 9232978617785735780UL, 1846595723557147156UL, + 3693191447114294312UL, 7386382894228588624UL, 14772765788457177249UL, + 2954553157691435449UL, 5909106315382870899UL, 11818212630765741799UL, + 2363642526153148359UL, 4727285052306296719UL, 9454570104612593439UL, + 1890914020922518687UL, 3781828041845037375UL, 7563656083690074751UL, + 15127312167380149503UL, 3025462433476029900UL, 6050924866952059801UL, + 12101849733904119602UL, 2420369946780823920UL, 4840739893561647841UL, + 9681479787123295682UL, 1936295957424659136UL, 3872591914849318272UL, + 7745183829698636545UL, 15490367659397273091UL, 3098073531879454618UL, + 6196147063758909236UL, 12392294127517818473UL, 2478458825503563694UL, + 4956917651007127389UL, 9913835302014254778UL, 1982767060402850955UL, + 3965534120805701911UL, 7931068241611403822UL, 15862136483222807645UL, + 3172427296644561529UL, 6344854593289123058UL, 12689709186578246116UL, + 2537941837315649223UL, 5075883674631298446UL, 10151767349262596893UL, + 2030353469852519378UL, 4060706939705038757UL, 8121413879410077514UL, + 16242827758820155028UL, 3248565551764031005UL, 6497131103528062011UL, + 12994262207056124023UL, 2598852441411224804UL, 5197704882822449609UL, + 10395409765644899218UL, 2079081953128979843UL, 4158163906257959687UL, + 8316327812515919374UL, 16632655625031838749UL, 3326531125006367749UL, + 6653062250012735499UL, 13306124500025470999UL, 2661224900005094199UL, + 5322449800010188399UL, 10644899600020376799UL, 2128979920004075359UL, + 4257959840008150719UL, 8515919680016301439UL, 17031839360032602879UL, + 3406367872006520575UL, 6812735744013041151UL, 13625471488026082303UL, + 2725094297605216460UL, 5450188595210432921UL, 10900377190420865842UL, + 2180075438084173168UL, 4360150876168346337UL, 8720301752336692674UL, + 17440603504673385348UL, 3488120700934677069UL, 6976241401869354139UL, + 13952482803738708279UL, 2790496560747741655UL, 5580993121495483311UL, + 11161986242990966623UL, 2232397248598193324UL, 4464794497196386649UL, + 8929588994392773298UL, 17859177988785546597UL, 3571835597757109319UL, + 7143671195514218638UL, 14287342391028437277UL, 2857468478205687455UL, + 5714936956411374911UL, 11429873912822749822UL, 2285974782564549964UL, + 4571949565129099928UL, 9143899130258199857UL, 1828779826051639971UL, + 3657559652103279943UL, 7315119304206559886UL, 14630238608413119772UL, + 2926047721682623954UL, 5852095443365247908UL, 11704190886730495817UL, + 2340838177346099163UL, 4681676354692198327UL, 9363352709384396654UL, + 1872670541876879330UL, 3745341083753758661UL, 7490682167507517323UL, + 14981364335015034646UL, 2996272867003006929UL, 5992545734006013858UL, + 11985091468012027717UL, 2397018293602405543UL, 4794036587204811087UL, + 9588073174409622174UL, 1917614634881924434UL, 3835229269763848869UL, + 7670458539527697739UL, 15340917079055395478UL, 3068183415811079095UL, + 6136366831622158191UL, 12272733663244316382UL, 2454546732648863276UL, + 4909093465297726553UL, 9818186930595453106UL, 1963637386119090621UL, + 3927274772238181242UL, 7854549544476362484UL, 15709099088952724969UL, + 3141819817790544993UL, 6283639635581089987UL, 12567279271162179975UL, + 2513455854232435995UL, 5026911708464871990UL, 10053823416929743980UL, + 2010764683385948796UL, 4021529366771897592UL, 8043058733543795184UL, + 16086117467087590369UL, 3217223493417518073UL, 6434446986835036147UL, + 12868893973670072295UL, 2573778794734014459UL, 5147557589468028918UL, + 10295115178936057836UL, 2059023035787211567UL, 4118046071574423134UL, + 8236092143148846269UL, 16472184286297692538UL, 3294436857259538507UL, + 6588873714519077015UL, 13177747429038154030UL, 2635549485807630806UL, + 5271098971615261612UL, 10542197943230523224UL, 2108439588646104644UL, + 4216879177292209289UL, 8433758354584418579UL, 16867516709168837158UL, + 3373503341833767431UL, 6747006683667534863UL, 13494013367335069727UL, + 2698802673467013945UL, 5397605346934027890UL, 10795210693868055781UL, + 2159042138773611156UL, 4318084277547222312UL, 8636168555094444625UL, + 17272337110188889250UL, 3454467422037777850UL, 6908934844075555700UL, + 13817869688151111400UL, 2763573937630222280UL, 5527147875260444560UL, + 11054295750520889120UL, 2210859150104177824UL, 4421718300208355648UL, + 8843436600416711296UL, 17686873200833422592UL, 3537374640166684518UL, + 7074749280333369037UL, 14149498560666738074UL, 2829899712133347614UL, + 5659799424266695229UL, 11319598848533390459UL, 2263919769706678091UL, + 4527839539413356183UL, 9055679078826712367UL, 1811135815765342473UL, + 3622271631530684947UL, 7244543263061369894UL, 14489086526122739788UL, + 2897817305224547957UL, 5795634610449095915UL, 11591269220898191830UL, + 2318253844179638366UL, 4636507688359276732UL, 9273015376718553464UL, + 1854603075343710692UL, 3709206150687421385UL, 7418412301374842771UL, + 14836824602749685542UL, 2967364920549937108UL, 5934729841099874217UL, + 11869459682199748434UL, 2373891936439949686UL, 4747783872879899373UL, + 9495567745759798747UL, 1899113549151959749UL, 3798227098303919498UL, + 7596454196607838997UL, 15192908393215677995UL, 3038581678643135599UL, + 6077163357286271198UL, 12154326714572542396UL, 2430865342914508479UL, + 4861730685829016958UL, 9723461371658033917UL, 1944692274331606783UL, + 3889384548663213566UL, 7778769097326427133UL, 15557538194652854267UL, + 3111507638930570853UL, 6223015277861141707UL, 12446030555722283414UL, + 2489206111144456682UL, 4978412222288913365UL, 9956824444577826731UL, + 1991364888915565346UL, 3982729777831130692UL, 7965459555662261385UL, + 15930919111324522770UL, 3186183822264904554UL, 6372367644529809108UL, + 12744735289059618216UL, 2548947057811923643UL, 5097894115623847286UL, + 10195788231247694572UL, 2039157646249538914UL, 4078315292499077829UL, + 8156630584998155658UL, 16313261169996311316UL, 3262652233999262263UL, + 6525304467998524526UL, 13050608935997049053UL, 2610121787199409810UL, + 5220243574398819621UL, 10440487148797639242UL, 2088097429759527848UL, + 4176194859519055697UL, 8352389719038111394UL, 16704779438076222788UL, + 3340955887615244557UL, 6681911775230489115UL, 13363823550460978230UL, + 2672764710092195646UL, 5345529420184391292UL, 10691058840368782584UL, + 2138211768073756516UL, 4276423536147513033UL, 8552847072295026067UL, + 17105694144590052135UL, 3421138828918010427UL, 6842277657836020854UL, + 13684555315672041708UL, 2736911063134408341UL, 5473822126268816683UL, + 10947644252537633366UL, 2189528850507526673UL, 4379057701015053346UL, + 8758115402030106693UL, 17516230804060213386UL, 3503246160812042677UL, + 7006492321624085354UL, 14012984643248170709UL, 2802596928649634141UL, + 5605193857299268283UL, 11210387714598536567UL, 2242077542919707313UL, + 4484155085839414626UL, 8968310171678829253UL, 17936620343357658507UL, + 3587324068671531701UL, 7174648137343063403UL, 14349296274686126806UL, + 2869859254937225361UL, 5739718509874450722UL, 11479437019748901445UL, + 2295887403949780289UL, 4591774807899560578UL, 9183549615799121156UL, + 1836709923159824231UL, 3673419846319648462UL, 7346839692639296924UL, + 14693679385278593849UL, 2938735877055718769UL, 5877471754111437539UL, + 11754943508222875079UL, 2350988701644575015UL, 4701977403289150031UL, + 9403954806578300063UL, 1880790961315660012UL, 3761581922631320025UL, + 7523163845262640050UL, 15046327690525280101UL, 3009265538105056020UL, + 6018531076210112040UL, 12037062152420224081UL, 2407412430484044816UL, + 4814824860968089632UL, 9629649721936179265UL, 1925929944387235853UL, + 3851859888774471706UL, 7703719777548943412UL, 15407439555097886824UL, + 3081487911019577364UL, 6162975822039154729UL, 12325951644078309459UL, + 2465190328815661891UL, 4930380657631323783UL, 9860761315262647567UL, + 1972152263052529513UL, 3944304526105059027UL, 7888609052210118054UL, + 15777218104420236108UL, 3155443620884047221UL, 6310887241768094443UL, + 12621774483536188886UL, 2524354896707237777UL, 5048709793414475554UL, + 10097419586828951109UL, 2019483917365790221UL, 4038967834731580443UL, + 8077935669463160887UL, 16155871338926321774UL, 3231174267785264354UL, + 6462348535570528709UL, 12924697071141057419UL, 2584939414228211483UL, + 5169878828456422967UL, 10339757656912845935UL, 2067951531382569187UL, + 4135903062765138374UL, 8271806125530276748UL, 16543612251060553497UL, + 3308722450212110699UL, 6617444900424221398UL, 13234889800848442797UL, + 2646977960169688559UL, 5293955920339377119UL, 10587911840678754238UL, + 2117582368135750847UL, 4235164736271501695UL, 8470329472543003390UL, + 16940658945086006781UL, 3388131789017201356UL, 6776263578034402712UL, + 13552527156068805425UL, 2710505431213761085UL, 5421010862427522170UL, + 10842021724855044340UL, 2168404344971008868UL, 4336808689942017736UL, + 8673617379884035472UL, 17347234759768070944UL, 3469446951953614188UL, + 6938893903907228377UL, 13877787807814456755UL, 2775557561562891351UL, + 5551115123125782702UL, 11102230246251565404UL, 2220446049250313080UL, + 4440892098500626161UL, 8881784197001252323UL, 17763568394002504646UL, + 3552713678800500929UL, 7105427357601001858UL, 14210854715202003717UL, + 2842170943040400743UL, 5684341886080801486UL, 11368683772161602973UL, + 2273736754432320594UL, 4547473508864641189UL, 9094947017729282379UL, + 1818989403545856475UL, 3637978807091712951UL, 7275957614183425903UL, + 14551915228366851806UL, 2910383045673370361UL, 5820766091346740722UL, + 11641532182693481445UL, 2328306436538696289UL, 4656612873077392578UL, + 9313225746154785156UL, 1862645149230957031UL, 3725290298461914062UL, + 7450580596923828125UL, 14901161193847656250UL, 2980232238769531250UL, + 5960464477539062500UL, 11920928955078125000UL, 2384185791015625000UL, + 4768371582031250000UL, 9536743164062500000UL, 1907348632812500000UL, + 3814697265625000000UL, 7629394531250000000UL, 15258789062500000000UL, + 3051757812500000000UL, 6103515625000000000UL, 12207031250000000000UL, + 2441406250000000000UL, 4882812500000000000UL, 9765625000000000000UL, + 1953125000000000000UL, 3906250000000000000UL, 7812500000000000000UL, + 15625000000000000000UL, 3125000000000000000UL, 6250000000000000000UL, + 12500000000000000000UL, 2500000000000000000UL, 5000000000000000000UL, + 10000000000000000000UL, 2000000000000000000UL, 4000000000000000000UL, + 8000000000000000000UL, 16000000000000000000UL, 3200000000000000000UL, + 6400000000000000000UL, 12800000000000000000UL, 2560000000000000000UL, + 5120000000000000000UL, 10240000000000000000UL, 2048000000000000000UL, + 4096000000000000000UL, 8192000000000000000UL, 16384000000000000000UL, + 3276800000000000000UL, 6553600000000000000UL, 13107200000000000000UL, + 2621440000000000000UL, 5242880000000000000UL, 10485760000000000000UL, + 2097152000000000000UL, 4194304000000000000UL, 8388608000000000000UL, + 16777216000000000000UL, 3355443200000000000UL, 6710886400000000000UL, + 13421772800000000000UL, 2684354560000000000UL, 5368709120000000000UL, + 10737418240000000000UL, 2147483648000000000UL, 4294967296000000000UL, + 8589934592000000000UL, 17179869184000000000UL, 3435973836800000000UL, + 6871947673600000000UL, 13743895347200000000UL, 2748779069440000000UL, + 5497558138880000000UL, 10995116277760000000UL, 2199023255552000000UL, + 4398046511104000000UL, 8796093022208000000UL, 17592186044416000000UL, + 3518437208883200000UL, 7036874417766400000UL, 14073748835532800000UL, + 2814749767106560000UL, 5629499534213120000UL, 11258999068426240000UL, + 2251799813685248000UL, 4503599627370496000UL, 9007199254740992000UL, + 18014398509481984000UL, 3602879701896396800UL, 7205759403792793600UL, + 14411518807585587200UL, 2882303761517117440UL, 5764607523034234880UL, + 11529215046068469760UL, 2305843009213693952UL, 4611686018427387904UL, + 9223372036854775808UL, 1844674407370955161UL, 3689348814741910323UL, + 7378697629483820646UL, 14757395258967641292UL, 2951479051793528258UL, + 5902958103587056517UL, 11805916207174113034UL, 2361183241434822606UL, + 4722366482869645213UL, 9444732965739290427UL, 1888946593147858085UL, + 3777893186295716170UL, 7555786372591432341UL, 15111572745182864683UL, + 3022314549036572936UL, 6044629098073145873UL, 12089258196146291747UL, + 2417851639229258349UL, 4835703278458516698UL, 9671406556917033397UL, + 1934281311383406679UL, 3868562622766813359UL, 7737125245533626718UL, + 15474250491067253436UL, 3094850098213450687UL, 6189700196426901374UL, + 12379400392853802748UL, 2475880078570760549UL, 4951760157141521099UL, + 9903520314283042199UL, 1980704062856608439UL, 3961408125713216879UL, + 7922816251426433759UL, 15845632502852867518UL, 3169126500570573503UL, + 6338253001141147007UL, 12676506002282294014UL, 2535301200456458802UL, + 5070602400912917605UL, 10141204801825835211UL, 2028240960365167042UL, + 4056481920730334084UL, 8112963841460668169UL, 16225927682921336339UL, + 3245185536584267267UL, 6490371073168534535UL, 12980742146337069071UL, + 2596148429267413814UL, 5192296858534827628UL, 10384593717069655257UL, + 2076918743413931051UL, 4153837486827862102UL, 8307674973655724205UL, + 16615349947311448411UL, 3323069989462289682UL, 6646139978924579364UL, + 13292279957849158729UL, 2658455991569831745UL, 5316911983139663491UL, + 10633823966279326983UL, 2126764793255865396UL, 4253529586511730793UL, + 8507059173023461586UL, 17014118346046923173UL, 3402823669209384634UL, + 6805647338418769269UL, 13611294676837538538UL, 2722258935367507707UL, + 5444517870735015415UL, 10889035741470030830UL, 2177807148294006166UL, + 4355614296588012332UL, 8711228593176024664UL, 17422457186352049329UL, + 3484491437270409865UL, 6968982874540819731UL, 13937965749081639463UL, + 2787593149816327892UL, 5575186299632655785UL, 11150372599265311570UL, + 2230074519853062314UL, 4460149039706124628UL, 8920298079412249256UL, + 17840596158824498513UL, 3568119231764899702UL, 7136238463529799405UL, + 14272476927059598810UL, 2854495385411919762UL, 5708990770823839524UL, + 11417981541647679048UL, 2283596308329535809UL, 4567192616659071619UL, + 9134385233318143238UL, 1826877046663628647UL, 3653754093327257295UL, + 7307508186654514591UL, 14615016373309029182UL, 2923003274661805836UL, + 5846006549323611672UL, 11692013098647223345UL, 2338402619729444669UL, + 4676805239458889338UL, 9353610478917778676UL, 1870722095783555735UL, + 3741444191567111470UL, 7482888383134222941UL, 14965776766268445882UL, + 2993155353253689176UL, 5986310706507378352UL, 11972621413014756705UL, + 2394524282602951341UL, 4789048565205902682UL, 9578097130411805364UL, + 1915619426082361072UL, 3831238852164722145UL, 7662477704329444291UL, + 15324955408658888583UL, 3064991081731777716UL, 6129982163463555433UL, + 12259964326927110866UL, 2451992865385422173UL, 4903985730770844346UL, + 9807971461541688693UL, 1961594292308337738UL, 3923188584616675477UL, + 7846377169233350954UL, 15692754338466701909UL, 3138550867693340381UL, + 6277101735386680763UL, 12554203470773361527UL, 2510840694154672305UL, + 5021681388309344611UL, 10043362776618689222UL, 2008672555323737844UL, + 4017345110647475688UL, 8034690221294951377UL, 16069380442589902755UL, + 3213876088517980551UL, 6427752177035961102UL, 12855504354071922204UL, + 2571100870814384440UL, 5142201741628768881UL, 10284403483257537763UL, + 2056880696651507552UL, 4113761393303015105UL, 8227522786606030210UL, + 16455045573212060421UL, 3291009114642412084UL, 6582018229284824168UL, + 13164036458569648337UL, 2632807291713929667UL, 5265614583427859334UL, + 10531229166855718669UL, 2106245833371143733UL, 4212491666742287467UL, + 8424983333484574935UL, 16849966666969149871UL, 3369993333393829974UL, + 6739986666787659948UL, 13479973333575319897UL, 2695994666715063979UL, + 5391989333430127958UL, 10783978666860255917UL, 2156795733372051183UL, + 4313591466744102367UL, 8627182933488204734UL, 17254365866976409468UL, + 3450873173395281893UL, 6901746346790563787UL, 13803492693581127574UL, + 2760698538716225514UL, 5521397077432451029UL, 11042794154864902059UL, + 2208558830972980411UL, 4417117661945960823UL, 8834235323891921647UL, + 17668470647783843295UL, 3533694129556768659UL, 7067388259113537318UL, + 14134776518227074636UL, 2826955303645414927UL, 5653910607290829854UL, + 11307821214581659709UL, 2261564242916331941UL, 4523128485832663883UL, + 9046256971665327767UL, 18092513943330655534UL, 3618502788666131106UL, + 7237005577332262213UL, 14474011154664524427UL, 2894802230932904885UL, + 5789604461865809771UL, 11579208923731619542UL, 2315841784746323908UL, + 4631683569492647816UL, 9263367138985295633UL, 1852673427797059126UL, + 3705346855594118253UL, 7410693711188236507UL, 14821387422376473014UL, + 2964277484475294602UL, 5928554968950589205UL, 11857109937901178411UL, + 2371421987580235682UL, 4742843975160471364UL, 9485687950320942729UL, + 1897137590064188545UL, 3794275180128377091UL, 7588550360256754183UL, + 15177100720513508366UL, 3035420144102701673UL, 6070840288205403346UL, + 12141680576410806693UL, 2428336115282161338UL, 4856672230564322677UL, + 9713344461128645354UL, 1942668892225729070UL, 3885337784451458141UL, + 7770675568902916283UL, 15541351137805832567UL, 3108270227561166513UL, + 6216540455122333026UL, 12433080910244666053UL, 2486616182048933210UL, + 4973232364097866421UL, 9946464728195732843UL, 1989292945639146568UL, + 3978585891278293137UL, 7957171782556586274UL, 15914343565113172548UL, + 3182868713022634509UL, 6365737426045269019UL, 12731474852090538039UL, + 2546294970418107607UL, 5092589940836215215UL, 10185179881672430431UL, + 2037035976334486086UL, 4074071952668972172UL, 8148143905337944345UL, + 16296287810675888690UL, 3259257562135177738UL, 6518515124270355476UL, + 13037030248540710952UL, 2607406049708142190UL, 5214812099416284380UL, + 10429624198832568761UL, 2085924839766513752UL, 4171849679533027504UL, + 8343699359066055009UL, 16687398718132110018UL, 3337479743626422003UL, + 6674959487252844007UL, 13349918974505688014UL, 2669983794901137602UL, + 5339967589802275205UL, 10679935179604550411UL, 2135987035920910082UL, + 4271974071841820164UL, 8543948143683640329UL, 17087896287367280659UL, + 3417579257473456131UL, 6835158514946912263UL, 13670317029893824527UL, + 2734063405978764905UL, 5468126811957529810UL, 10936253623915059621UL, + 2187250724783011924UL, 4374501449566023848UL, 8749002899132047697UL, + 17498005798264095394UL, 3499601159652819078UL, 6999202319305638157UL, + 13998404638611276315UL, 2799680927722255263UL, 5599361855444510526UL, + 11198723710889021052UL, 2239744742177804210UL, 4479489484355608421UL, + 8958978968711216842UL, 17917957937422433684UL, 3583591587484486736UL, + 7167183174968973473UL, 14334366349937946947UL, 2866873269987589389UL, + 5733746539975178779UL, 11467493079950357558UL, 2293498615990071511UL, + 4586997231980143023UL, 9173994463960286046UL, 1834798892792057209UL, + 3669597785584114418UL, 7339195571168228837UL, 14678391142336457674UL, + 2935678228467291534UL, 5871356456934583069UL, 11742712913869166139UL, + 2348542582773833227UL, 4697085165547666455UL, 9394170331095332911UL, + 1878834066219066582UL, 3757668132438133164UL, 7515336264876266329UL, + 15030672529752532658UL, 3006134505950506531UL, 6012269011901013063UL, + 12024538023802026126UL, 2404907604760405225UL, 4809815209520810450UL, + 9619630419041620901UL, 1923926083808324180UL, 3847852167616648360UL, + 7695704335233296721UL, 15391408670466593442UL, 3078281734093318688UL, + 6156563468186637376UL, 12313126936373274753UL, 2462625387274654950UL, + 4925250774549309901UL, 9850501549098619803UL, 1970100309819723960UL, + 3940200619639447921UL, 7880401239278895842UL, 15760802478557791684UL, + 3152160495711558336UL, 6304320991423116673UL, 12608641982846233347UL, + 2521728396569246669UL, 5043456793138493339UL, 10086913586276986678UL, + 2017382717255397335UL, 4034765434510794671UL, 8069530869021589342UL, + 16139061738043178685UL, 3227812347608635737UL, 6455624695217271474UL, + 12911249390434542948UL, 2582249878086908589UL, 5164499756173817179UL, + 10328999512347634358UL, 2065799902469526871UL, 4131599804939053743UL, + 8263199609878107486UL, 16526399219756214973UL, 3305279843951242994UL, + 6610559687902485989UL, 13221119375804971979UL, 2644223875160994395UL, + 5288447750321988791UL, 10576895500643977583UL, 2115379100128795516UL, + 4230758200257591033UL, 8461516400515182066UL, 16923032801030364133UL, + 3384606560206072826UL, 6769213120412145653UL, 13538426240824291306UL, + 2707685248164858261UL, 5415370496329716522UL, 10830740992659433045UL, + 2166148198531886609UL, 4332296397063773218UL, 8664592794127546436UL, + 17329185588255092872UL, 3465837117651018574UL, 6931674235302037148UL, + 13863348470604074297UL, 2772669694120814859UL, 5545339388241629719UL, + 11090678776483259438UL, 2218135755296651887UL, 4436271510593303775UL, + 8872543021186607550UL, 17745086042373215101UL, 3549017208474643020UL, + 7098034416949286040UL, 14196068833898572081UL, 2839213766779714416UL, + 5678427533559428832UL, 11356855067118857664UL, 2271371013423771532UL, + 4542742026847543065UL, 9085484053695086131UL, 1817096810739017226UL, + 3634193621478034452UL, 7268387242956068905UL, 14536774485912137810UL, + 2907354897182427562UL, 5814709794364855124UL, 11629419588729710248UL, + 2325883917745942049UL, 4651767835491884099UL, 9303535670983768199UL, + 1860707134196753639UL, 3721414268393507279UL, 7442828536787014559UL, + 14885657073574029118UL, 2977131414714805823UL, 5954262829429611647UL, + 11908525658859223294UL, 2381705131771844658UL, 4763410263543689317UL, + 9526820527087378635UL, 1905364105417475727UL, 3810728210834951454UL, + 7621456421669902908UL, 15242912843339805817UL, 3048582568667961163UL, + 6097165137335922326UL, 12194330274671844653UL, 2438866054934368930UL, + 4877732109868737861UL, 9755464219737475723UL, 1951092843947495144UL, + 3902185687894990289UL, 7804371375789980578UL, 15608742751579961156UL, + 3121748550315992231UL, 6243497100631984462UL, 12486994201263968925UL, + 2497398840252793785UL, 4994797680505587570UL, 9989595361011175140UL, + 1997919072202235028UL, 3995838144404470056UL, 7991676288808940112UL, + 15983352577617880224UL, 3196670515523576044UL, 6393341031047152089UL, + 12786682062094304179UL, 2557336412418860835UL, 5114672824837721671UL, + 10229345649675443343UL, 2045869129935088668UL, 4091738259870177337UL, + 8183476519740354675UL, 16366953039480709350UL, 3273390607896141870UL, + 6546781215792283740UL, 13093562431584567480UL, 2618712486316913496UL, + 5237424972633826992UL, 10474849945267653984UL, 2094969989053530796UL, + 4189939978107061593UL, 8379879956214123187UL, 16759759912428246374UL, + 3351951982485649274UL, 6703903964971298549UL, 13407807929942597099UL, + 2681561585988519419UL, 5363123171977038839UL, 10726246343954077679UL, + 2145249268790815535UL, 4290498537581631071UL, 8580997075163262143UL, + 17161994150326524287UL, 3432398830065304857UL, 6864797660130609714UL, + 13729595320261219429UL, 2745919064052243885UL, 5491838128104487771UL, + 10983676256208975543UL, 2196735251241795108UL, 4393470502483590217UL, + 8786941004967180435UL, 17573882009934360870UL, 3514776401986872174UL, + 7029552803973744348UL, 14059105607947488696UL, 2811821121589497739UL, + 5623642243178995478UL, 11247284486357990957UL, 2249456897271598191UL, + 4498913794543196382UL, 8997827589086392765UL, 17995655178172785531UL, + 3599131035634557106UL, 7198262071269114212UL, 14396524142538228424UL, + 2879304828507645684UL, 5758609657015291369UL, 11517219314030582739UL, + 2303443862806116547UL, 4606887725612233095UL, 9213775451224466191UL, + 1842755090244893238UL, 3685510180489786476UL, 7371020360979572953UL, + 14742040721959145907UL, 2948408144391829181UL, 5896816288783658362UL, + 11793632577567316725UL, 2358726515513463345UL, 4717453031026926690UL, + 9434906062053853380UL, 1886981212410770676UL, 3773962424821541352UL, + 7547924849643082704UL, 15095849699286165408UL, 3019169939857233081UL, + 6038339879714466163UL, 12076679759428932327UL, 2415335951885786465UL, + 4830671903771572930UL, 9661343807543145861UL, 1932268761508629172UL, + 3864537523017258344UL, 7729075046034516689UL, 15458150092069033378UL, + 3091630018413806675UL, 6183260036827613351UL, 12366520073655226703UL, + 2473304014731045340UL, 4946608029462090681UL, 9893216058924181362UL, + 1978643211784836272UL, 3957286423569672544UL, 7914572847139345089UL, + 15829145694278690179UL, 3165829138855738035UL, 6331658277711476071UL, + 12663316555422952143UL, 2532663311084590428UL, 5065326622169180857UL, + 10130653244338361715UL, 2026130648867672343UL, 4052261297735344686UL, + 8104522595470689372UL, 16209045190941378744UL, 3241809038188275748UL, + 6483618076376551497UL, 12967236152753102995UL, 2593447230550620599UL, + 5186894461101241198UL, 10373788922202482396UL, 2074757784440496479UL, + 4149515568880992958UL, 8299031137761985917UL, 16598062275523971834UL, + 3319612455104794366UL, 6639224910209588733UL, 13278449820419177467UL, + 2655689964083835493UL, 5311379928167670986UL, 10622759856335341973UL, + 2124551971267068394UL, 4249103942534136789UL, 8498207885068273579UL, + 16996415770136547158UL, 3399283154027309431UL, 6798566308054618863UL, + 13597132616109237726UL, 2719426523221847545UL, 5438853046443695090UL, + 10877706092887390181UL, 2175541218577478036UL, 4351082437154956072UL, + 8702164874309912144UL, 17404329748619824289UL, 3480865949723964857UL, + 6961731899447929715UL, 13923463798895859431UL, 2784692759779171886UL, + 5569385519558343772UL, 11138771039116687545UL, 2227754207823337509UL, + 4455508415646675018UL, 8911016831293350036UL, 17822033662586700072UL, + 3564406732517340014UL, 7128813465034680029UL, 14257626930069360058UL, + 2851525386013872011UL, 5703050772027744023UL, 11406101544055488046UL, + 2281220308811097609UL, 4562440617622195218UL, 9124881235244390437UL, + 1824976247048878087UL, 3649952494097756174UL, 7299904988195512349UL, + 14599809976391024699UL, 2919961995278204939UL, 5839923990556409879UL, + 11679847981112819759UL, 2335969596222563951UL, 4671939192445127903UL, + 9343878384890255807UL, 1868775676978051161UL, 3737551353956102323UL, + 7475102707912204646UL, 14950205415824409292UL, 2990041083164881858UL, + 5980082166329763716UL, 11960164332659527433UL, 2392032866531905486UL, + 4784065733063810973UL, 9568131466127621947UL, 1913626293225524389UL, + 3827252586451048778UL, 7654505172902097557UL, 15309010345804195115UL, + 3061802069160839023UL, 6123604138321678046UL, 12247208276643356092UL, + 2449441655328671218UL, 4898883310657342436UL, 9797766621314684873UL, + 1959553324262936974UL, 3919106648525873949UL, 7838213297051747899UL, + 15676426594103495798UL, 3135285318820699159UL, 6270570637641398319UL, + 12541141275282796638UL, 2508228255056559327UL, 5016456510113118655UL, + 10032913020226237310UL, 2006582604045247462UL, 4013165208090494924UL, + 8026330416180989848UL, 16052660832361979697UL, 3210532166472395939UL, + 6421064332944791878UL, 12842128665889583757UL, 2568425733177916751UL, + 5136851466355833503UL, 10273702932711667006UL, 2054740586542333401UL, + 4109481173084666802UL, 8218962346169333605UL, 16437924692338667210UL, + 3287584938467733442UL, 6575169876935466884UL, 13150339753870933768UL, + 2630067950774186753UL, 5260135901548373507UL, 10520271803096747014UL, + 2104054360619349402UL, 4208108721238698805UL, 8416217442477397611UL, + 16832434884954795223UL, 3366486976990959044UL, 6732973953981918089UL, + 13465947907963836178UL, 2693189581592767235UL, 5386379163185534471UL, + 10772758326371068942UL, 2154551665274213788UL, 4309103330548427577UL, + 8618206661096855154UL, 17236413322193710308UL, 3447282664438742061UL, + 6894565328877484123UL, 13789130657754968246UL, 2757826131550993649UL, + 5515652263101987298UL, 11031304526203974597UL, 2206260905240794919UL, + 4412521810481589838UL, 8825043620963179677UL, 17650087241926359355UL, + 3530017448385271871UL, 7060034896770543742UL, 14120069793541087484UL, + 2824013958708217496UL, 5648027917416434993UL, 11296055834832869987UL, + 2259211166966573997UL, 4518422333933147995UL, 9036844667866295990UL, + 18073689335732591980UL, 3614737867146518396UL, 7229475734293036792UL, + 14458951468586073584UL, 2891790293717214716UL, 5783580587434429433UL, + 11567161174868858867UL, 2313432234973771773UL, 4626864469947543547UL, + 9253728939895087094UL, 1850745787979017418UL, 3701491575958034837UL, + 7402983151916069675UL, 14805966303832139350UL, 2961193260766427870UL, + 5922386521532855740UL, 11844773043065711480UL, 2368954608613142296UL, + 4737909217226284592UL, 9475818434452569184UL, 1895163686890513836UL, + 3790327373781027673UL, 7580654747562055347UL, 15161309495124110694UL, + 3032261899024822138UL, 6064523798049644277UL, 12129047596099288555UL, + 2425809519219857711UL, 4851619038439715422UL, 9703238076879430844UL, + 1940647615375886168UL, 3881295230751772337UL, 7762590461503544675UL, + 15525180923007089351UL, 3105036184601417870UL, 6210072369202835740UL, + 12420144738405671481UL, 2484028947681134296UL, 4968057895362268592UL, + 9936115790724537184UL, 1987223158144907436UL, 3974446316289814873UL, + 7948892632579629747UL, 15897785265159259495UL, 3179557053031851899UL, + 6359114106063703798UL, 12718228212127407596UL, 2543645642425481519UL, + 5087291284850963038UL, 10174582569701926077UL, 2034916513940385215UL, + 4069833027880770430UL, 8139666055761540861UL, 16279332111523081723UL, + 3255866422304616344UL, 6511732844609232689UL, 13023465689218465379UL, + 2604693137843693075UL, 5209386275687386151UL, 10418772551374772303UL, + 2083754510274954460UL, 4167509020549908921UL, 8335018041099817842UL, + 16670036082199635685UL, 3334007216439927137UL, 6668014432879854274UL, + 13336028865759708548UL, 2667205773151941709UL, 5334411546303883419UL, + 10668823092607766838UL, 2133764618521553367UL, 4267529237043106735UL, + 8535058474086213470UL, 17070116948172426941UL, 3414023389634485388UL, + 6828046779268970776UL, 13656093558537941553UL, 2731218711707588310UL, + 5462437423415176621UL, 10924874846830353242UL, 2184974969366070648UL, + 4369949938732141297UL, 8739899877464282594UL, 17479799754928565188UL, + 3495959950985713037UL, 6991919901971426075UL, 13983839803942852150UL, + 2796767960788570430UL, 5593535921577140860UL, 11187071843154281720UL, + 2237414368630856344UL, 4474828737261712688UL, 8949657474523425376UL, + 17899314949046850752UL, 3579862989809370150UL, 7159725979618740301UL, + 14319451959237480602UL, 2863890391847496120UL, 5727780783694992240UL, + 11455561567389984481UL, 2291112313477996896UL, 4582224626955993792UL, + 9164449253911987585UL, 1832889850782397517UL, 3665779701564795034UL, + 7331559403129590068UL, 14663118806259180136UL, 2932623761251836027UL, + 5865247522503672054UL, 11730495045007344109UL, 2346099009001468821UL, + 4692198018002937643UL, 9384396036005875287UL, 1876879207201175057UL, + 3753758414402350114UL, 7507516828804700229UL, 15015033657609400459UL, + 3003006731521880091UL, 6006013463043760183UL, 12012026926087520367UL, + 2402405385217504073UL, 4804810770435008147UL, 9609621540870016294UL, + 1921924308174003258UL, 3843848616348006517UL, 7687697232696013035UL, + 15375394465392026070UL, 3075078893078405214UL, 6150157786156810428UL, + 12300315572313620856UL, 2460063114462724171UL, 4920126228925448342UL, + 9840252457850896685UL, 1968050491570179337UL, 3936100983140358674UL, + 7872201966280717348UL, 15744403932561434696UL, 3148880786512286939UL, + 6297761573024573878UL, 12595523146049147757UL, 2519104629209829551UL, + 5038209258419659102UL, 10076418516839318205UL, 2015283703367863641UL, + 4030567406735727282UL, 8061134813471454564UL, 16122269626942909129UL, + 3224453925388581825UL, 6448907850777163651UL, 12897815701554327303UL, + 2579563140310865460UL, 5159126280621730921UL, 10318252561243461842UL, + 2063650512248692368UL, 4127301024497384737UL, 8254602048994769474UL, + 16509204097989538948UL, 3301840819597907789UL, 6603681639195815579UL, + 13207363278391631158UL, 2641472655678326231UL, 5282945311356652463UL, + 10565890622713304927UL, 2113178124542660985UL, 4226356249085321970UL, + 8452712498170643941UL, 16905424996341287883UL, 3381084999268257576UL, + 6762169998536515153UL, 13524339997073030306UL, 2704867999414606061UL, + 5409735998829212122UL, 10819471997658424245UL, 2163894399531684849UL, + 4327788799063369698UL, 8655577598126739396UL, 17311155196253478792UL, + 3462231039250695758UL, 6924462078501391516UL, 13848924157002783033UL, + 2769784831400556606UL, 5539569662801113213UL, 11079139325602226427UL, + 2215827865120445285UL, 4431655730240890570UL, 8863311460481781141UL, + 17726622920963562283UL, 3545324584192712456UL, 7090649168385424913UL, + 14181298336770849826UL, 2836259667354169965UL, 5672519334708339930UL, + 11345038669416679861UL, 2269007733883335972UL, 4538015467766671944UL, + 9076030935533343889UL, 18152061871066687778UL, 3630412374213337555UL, + 7260824748426675111UL, 14521649496853350222UL, 2904329899370670044UL, + 5808659798741340089UL, 11617319597482680178UL, 2323463919496536035UL, + 4646927838993072071UL, 9293855677986144142UL, 1858771135597228828UL, + 3717542271194457656UL, 7435084542388915313UL, 14870169084777830627UL, + 2974033816955566125UL, 5948067633911132251UL, 11896135267822264502UL, + 2379227053564452900UL, 4758454107128905800UL, 9516908214257811601UL, + 1903381642851562320UL, 3806763285703124640UL, 7613526571406249281UL, + 15227053142812498563UL, 3045410628562499712UL, 6090821257124999425UL, + 12181642514249998850UL, 2436328502849999770UL, 4872657005699999540UL, + 9745314011399999080UL, 1949062802279999816UL, 3898125604559999632UL, + 7796251209119999264UL, 15592502418239998528UL, 3118500483647999705UL, + 6237000967295999411UL, 12474001934591998822UL, 2494800386918399764UL, + 4989600773836799529UL, 9979201547673599058UL, 1995840309534719811UL, + 3991680619069439623UL, 7983361238138879246UL, 15966722476277758493UL, + 3193344495255551698UL, 6386688990511103397UL, 12773377981022206794UL, + 2554675596204441358UL, 5109351192408882717UL, 10218702384817765435UL, + 2043740476963553087UL, 4087480953927106174UL, 8174961907854212348UL, + 16349923815708424697UL, 3269984763141684939UL, 6539969526283369878UL, + 13079939052566739757UL, 2615987810513347951UL, 5231975621026695903UL, + 10463951242053391806UL, 2092790248410678361UL, 4185580496821356722UL, + 8371160993642713444UL, 16742321987285426889UL, 3348464397457085377UL, + 6696928794914170755UL, 13393857589828341511UL, 2678771517965668302UL, + 5357543035931336604UL, 10715086071862673209UL, 2143017214372534641UL, + 4286034428745069283UL, 8572068857490138567UL, 17144137714980277135UL, + 3428827542996055427UL, 6857655085992110854UL, 13715310171984221708UL, + 2743062034396844341UL, 5486124068793688683UL, 10972248137587377366UL, + 2194449627517475473UL, 4388899255034950946UL, 8777798510069901893UL, + 17555597020139803786UL, 3511119404027960757UL, 7022238808055921514UL, + 14044477616111843029UL, 2808895523222368605UL, 5617791046444737211UL, + 11235582092889474423UL, 2247116418577894884UL, 4494232837155789769UL, + 8988465674311579538UL, 17976931348623159077UL, 3595386269724631815UL, + 7190772539449263630UL, 14381545078898527261UL, 2876309015779705452UL, + 5752618031559410904UL, 11505236063118821809UL, 2301047212623764361UL, + 4602094425247528723UL, 9204188850495057447UL, 1840837770099011489UL, + 3681675540198022979UL, 7363351080396045958UL, + }; + + TensExponentTable = new[] + { + -323, -323, -322, -322, -322, -322, -321, -321, -321, -320, -320, -320, + -319, -319, -319, -319, -318, -318, -318, -317, -317, -317, -316, -316, + -316, -316, -315, -315, -315, -314, -314, -314, -313, -313, -313, -313, + -312, -312, -312, -311, -311, -311, -310, -310, -310, -310, -309, -309, + -309, -308, -308, -308, -307, -307, -307, -307, -306, -306, -306, -305, + -305, -305, -304, -304, -304, -304, -303, -303, -303, -302, -302, -302, + -301, -301, -301, -301, -300, -300, -300, -299, -299, -299, -298, -298, + -298, -298, -297, -297, -297, -296, -296, -296, -295, -295, -295, -295, + -294, -294, -294, -293, -293, -293, -292, -292, -292, -291, -291, -291, + -291, -290, -290, -290, -289, -289, -289, -288, -288, -288, -288, -287, + -287, -287, -286, -286, -286, -285, -285, -285, -285, -284, -284, -284, + -283, -283, -283, -282, -282, -282, -282, -281, -281, -281, -280, -280, + -280, -279, -279, -279, -279, -278, -278, -278, -277, -277, -277, -276, + -276, -276, -276, -275, -275, -275, -274, -274, -274, -273, -273, -273, + -273, -272, -272, -272, -271, -271, -271, -270, -270, -270, -270, -269, + -269, -269, -268, -268, -268, -267, -267, -267, -267, -266, -266, -266, + -265, -265, -265, -264, -264, -264, -263, -263, -263, -263, -262, -262, + -262, -261, -261, -261, -260, -260, -260, -260, -259, -259, -259, -258, + -258, -258, -257, -257, -257, -257, -256, -256, -256, -255, -255, -255, + -254, -254, -254, -254, -253, -253, -253, -252, -252, -252, -251, -251, + -251, -251, -250, -250, -250, -249, -249, -249, -248, -248, -248, -248, + -247, -247, -247, -246, -246, -246, -245, -245, -245, -245, -244, -244, + -244, -243, -243, -243, -242, -242, -242, -242, -241, -241, -241, -240, + -240, -240, -239, -239, -239, -239, -238, -238, -238, -237, -237, -237, + -236, -236, -236, -235, -235, -235, -235, -234, -234, -234, -233, -233, + -233, -232, -232, -232, -232, -231, -231, -231, -230, -230, -230, -229, + -229, -229, -229, -228, -228, -228, -227, -227, -227, -226, -226, -226, + -226, -225, -225, -225, -224, -224, -224, -223, -223, -223, -223, -222, + -222, -222, -221, -221, -221, -220, -220, -220, -220, -219, -219, -219, + -218, -218, -218, -217, -217, -217, -217, -216, -216, -216, -215, -215, + -215, -214, -214, -214, -214, -213, -213, -213, -212, -212, -212, -211, + -211, -211, -211, -210, -210, -210, -209, -209, -209, -208, -208, -208, + -208, -207, -207, -207, -206, -206, -206, -205, -205, -205, -204, -204, + -204, -204, -203, -203, -203, -202, -202, -202, -201, -201, -201, -201, + -200, -200, -200, -199, -199, -199, -198, -198, -198, -198, -197, -197, + -197, -196, -196, -196, -195, -195, -195, -195, -194, -194, -194, -193, + -193, -193, -192, -192, -192, -192, -191, -191, -191, -190, -190, -190, + -189, -189, -189, -189, -188, -188, -188, -187, -187, -187, -186, -186, + -186, -186, -185, -185, -185, -184, -184, -184, -183, -183, -183, -183, + -182, -182, -182, -181, -181, -181, -180, -180, -180, -180, -179, -179, + -179, -178, -178, -178, -177, -177, -177, -176, -176, -176, -176, -175, + -175, -175, -174, -174, -174, -173, -173, -173, -173, -172, -172, -172, + -171, -171, -171, -170, -170, -170, -170, -169, -169, -169, -168, -168, + -168, -167, -167, -167, -167, -166, -166, -166, -165, -165, -165, -164, + -164, -164, -164, -163, -163, -163, -162, -162, -162, -161, -161, -161, + -161, -160, -160, -160, -159, -159, -159, -158, -158, -158, -158, -157, + -157, -157, -156, -156, -156, -155, -155, -155, -155, -154, -154, -154, + -153, -153, -153, -152, -152, -152, -152, -151, -151, -151, -150, -150, + -150, -149, -149, -149, -149, -148, -148, -148, -147, -147, -147, -146, + -146, -146, -145, -145, -145, -145, -144, -144, -144, -143, -143, -143, + -142, -142, -142, -142, -141, -141, -141, -140, -140, -140, -139, -139, + -139, -139, -138, -138, -138, -137, -137, -137, -136, -136, -136, -136, + -135, -135, -135, -134, -134, -134, -133, -133, -133, -133, -132, -132, + -132, -131, -131, -131, -130, -130, -130, -130, -129, -129, -129, -128, + -128, -128, -127, -127, -127, -127, -126, -126, -126, -125, -125, -125, + -124, -124, -124, -124, -123, -123, -123, -122, -122, -122, -121, -121, + -121, -121, -120, -120, -120, -119, -119, -119, -118, -118, -118, -117, + -117, -117, -117, -116, -116, -116, -115, -115, -115, -114, -114, -114, + -114, -113, -113, -113, -112, -112, -112, -111, -111, -111, -111, -110, + -110, -110, -109, -109, -109, -108, -108, -108, -108, -107, -107, -107, + -106, -106, -106, -105, -105, -105, -105, -104, -104, -104, -103, -103, + -103, -102, -102, -102, -102, -101, -101, -101, -100, -100, -100, -99, + -99, -99, -99, -98, -98, -98, -97, -97, -97, -96, -96, -96, + -96, -95, -95, -95, -94, -94, -94, -93, -93, -93, -93, -92, + -92, -92, -91, -91, -91, -90, -90, -90, -89, -89, -89, -89, + -88, -88, -88, -87, -87, -87, -86, -86, -86, -86, -85, -85, + -85, -84, -84, -84, -83, -83, -83, -83, -82, -82, -82, -81, + -81, -81, -80, -80, -80, -80, -79, -79, -79, -78, -78, -78, + -77, -77, -77, -77, -76, -76, -76, -75, -75, -75, -74, -74, + -74, -74, -73, -73, -73, -72, -72, -72, -71, -71, -71, -71, + -70, -70, -70, -69, -69, -69, -68, -68, -68, -68, -67, -67, + -67, -66, -66, -66, -65, -65, -65, -65, -64, -64, -64, -63, + -63, -63, -62, -62, -62, -62, -61, -61, -61, -60, -60, -60, + -59, -59, -59, -58, -58, -58, -58, -57, -57, -57, -56, -56, + -56, -55, -55, -55, -55, -54, -54, -54, -53, -53, -53, -52, + -52, -52, -52, -51, -51, -51, -50, -50, -50, -49, -49, -49, + -49, -48, -48, -48, -47, -47, -47, -46, -46, -46, -46, -45, + -45, -45, -44, -44, -44, -43, -43, -43, -43, -42, -42, -42, + -41, -41, -41, -40, -40, -40, -40, -39, -39, -39, -38, -38, + -38, -37, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, + -34, -34, -34, -33, -33, -33, -32, -32, -32, -31, -31, -31, + -30, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, + -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -24, + -23, -23, -23, -22, -22, -22, -21, -21, -21, -21, -20, -20, + -20, -19, -19, -19, -18, -18, -18, -18, -17, -17, -17, -16, + -16, -16, -15, -15, -15, -15, -14, -14, -14, -13, -13, -13, + -12, -12, -12, -12, -11, -11, -11, -10, -10, -10, -9, -9, + -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6, -6, + -5, -5, -5, -4, -4, -4, -3, -3, -3, -3, -2, -2, + -2, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 2, + 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, + 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, + 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, + 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, + 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, + 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 31, + 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, + 35, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, + 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 41, + 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, + 45, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 49, + 49, 49, 50, 50, 50, 50, 51, 51, 51, 52, 52, 52, + 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, + 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, + 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, + 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 66, 67, + 67, 67, 68, 68, 68, 69, 69, 69, 69, 70, 70, 70, + 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 74, 74, + 74, 75, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, + 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, + 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 84, 85, + 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 88, + 89, 89, 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, + 92, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 96, + 96, 96, 97, 97, 97, 97, 98, 98, 98, 99, 99, 99, + 100, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, + 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 106, + 107, 107, 107, 108, 108, 108, 109, 109, 109, 109, 110, 110, + 110, 111, 111, 111, 112, 112, 112, 112, 113, 113, 113, 114, + 114, 114, 115, 115, 115, 116, 116, 116, 116, 117, 117, 117, + 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 121, 121, + 121, 122, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, + 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, + 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 131, 132, + 132, 132, 133, 133, 133, 134, 134, 134, 134, 135, 135, 135, + 136, 136, 136, 137, 137, 137, 137, 138, 138, 138, 139, 139, + 139, 140, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, + 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, + 147, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, + 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 153, + 154, 154, 154, 155, 155, 155, 156, 156, 156, 156, 157, 157, + 157, 158, 158, 158, 159, 159, 159, 159, 160, 160, 160, 161, + 161, 161, 162, 162, 162, 162, 163, 163, 163, 164, 164, 164, + 165, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, + 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 171, + 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, + 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 178, 179, + 179, 179, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, + 183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 186, 186, + 186, 187, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, + 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, + 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 196, 197, + 197, 197, 198, 198, 198, 199, 199, 199, 199, 200, 200, 200, + 201, 201, 201, 202, 202, 202, 202, 203, 203, 203, 204, 204, + 204, 205, 205, 205, 206, 206, 206, 206, 207, 207, 207, 208, + 208, 208, 209, 209, 209, 209, 210, 210, 210, 211, 211, 211, + 212, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, + 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 218, + 219, 219, 219, 220, 220, 220, 221, 221, 221, 221, 222, 222, + 222, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 226, + 226, 226, 227, 227, 227, 227, 228, 228, 228, 229, 229, 229, + 230, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, + 233, 234, 234, 234, 234, 235, 235, 235, 236, 236, 236, 237, + 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, + 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 243, 244, + 244, 244, 245, 245, 245, 246, 246, 246, 246, 247, 247, 247, + 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 251, 251, + 251, 252, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255, + 255, 255, 255, 256, 256, 256, 257, 257, 257, 258, 258, 258, + 258, 259, 259, 259, 260, 260, 260, 261, 261, 261, 261, 262, + 262, 262, 263, 263, 263, 264, 264, 264, 265, 265, 265, 265, + 266, 266, 266, 267, 267, 267, 268, 268, 268, 268, 269, 269, + 269, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 273, + 273, 273, 274, 274, 274, 274, 275, 275, 275, 276, 276, 276, + 277, 277, 277, 277, 278, 278, 278, 279, 279, 279, 280, 280, + 280, 280, 281, 281, 281, 282, 282, 282, 283, 283, 283, 283, + 284, 284, 284, 285, 285, 285, 286, 286, 286, 286, 287, 287, + 287, 288, 288, 288, 289, 289, 289, 289, 290, 290, 290, 291, + 291, 291, 292, 292, 292, 293, 293, 293, + }; + + DigitLowerTable = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + DigitUpperTable = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + TenPowersList = new[] + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L, + 10000000000L, + 100000000000L, + 1000000000000L, + 10000000000000L, + 100000000000000L, + 1000000000000000L, + 10000000000000000L, + 100000000000000000L, + 1000000000000000000L, + }; + + DecHexDigits = new[] + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + }; + } + } + +} diff --git a/JSIL.mscorlib/JSIL/System/NumberFormatter.cs b/JSIL.mscorlib/JSIL/System/NumberFormatter.cs new file mode 100644 index 000000000..6467711af --- /dev/null +++ b/JSIL.mscorlib/JSIL/System/NumberFormatter.cs @@ -0,0 +1,2324 @@ +// +// mcs/class/corlib/System/NumberFormatter.cs +// +// Author: +// Kazuki Oikawa (kazuki@panicode.com) +// Eyal Alaluf (eyala@mainsoft.com) +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// Copyright (C) 2008 Mainsoft Co. (http://www.mainsoft.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Text; +using System.Threading; + +namespace JSIL.System +{ + public sealed partial class NumberFormatter + { + #region Static Fields + + private const int DefaultExpPrecision = 6; + private const int HundredMillion = 100000000; + private const long SeventeenDigitsThreshold = 10000000000000000; + private const ulong ULongDivHundredMillion = UInt64.MaxValue/HundredMillion; + private const ulong ULongModHundredMillion = 1 + UInt64.MaxValue%HundredMillion; + + private const int DoubleBitsExponentShift = 52; + private const int DoubleBitsExponentMask = 0x7ff; + private const long DoubleBitsMantissaMask = 0xfffffffffffff; + private const int DecimalBitsScaleMask = 0x1f0000; + + private const int SingleDefPrecision = 7; + private const int DoubleDefPrecision = 15; + private const int Int32DefPrecision = 10; + private const int UInt32DefPrecision = 10; + private const int Int64DefPrecision = 19; + private const int UInt64DefPrecision = 20; + private const int DecimalDefPrecision = 100; + private const int TenPowersListLength = 19; + + private const double MinRoundtripVal = -1.79769313486231E+308; + private const double MaxRoundtripVal = 1.79769313486231E+308; + + // The below arrays are taken from mono/metatdata/number-formatter.h + + private static readonly ulong[] MantissaBitsTable; + private static readonly int[] TensExponentTable; + private static readonly char[] DigitLowerTable; + private static readonly char[] DigitUpperTable; + private static readonly long[] TenPowersList; + + // DecHexDigits s a translation table from a decimal number to its + // digits hexadecimal representation (e.g. DecHexDigits [34] = 0x34). + private static readonly int[] DecHexDigits; + + + static NumberFormatter() + { + GetFormatterTables(out MantissaBitsTable, out TensExponentTable, + out DigitLowerTable, out DigitUpperTable, out TenPowersList, out DecHexDigits); + } + + private static long GetTenPowerOf(int i) + { + return TenPowersList[i]; + } + + #endregion Static Fields + + #region Fields + + private NumberFormatInfo _nfi; + + //part of the private stringbuffer + private char[] _cbuf; + + private bool _NaN; + private bool _infinity; + private bool _isCustomFormat; + private bool _specifierIsUpper; + private bool _positive; + private char _specifier; + private int _precision; + private int _defPrecision; + + private int _digitsLen; + private int _offset; // Represent the first digit offset. + private int _decPointPos; + + // The following fields are a hexadeimal representation of the digits. + // For instance _val = 0x234 represents the digits '2', '3', '4'. + private uint _val1; // Digits 0 - 7. + private uint _val2; // Digits 8 - 15. + private uint _val3; // Digits 16 - 23. + private uint _val4; // Digits 23 - 31. Only needed for decimals. + + #endregion Fields + + #region Constructor Helpers + + // Translate an unsigned int to hexadecimal digits. + // i.e. 123456789 is represented by _val1 = 0x23456789 and _val2 = 0x1 + private void InitDecHexDigits(uint value) + { + if (value >= HundredMillion) + { + int div1 = (int) (value/HundredMillion); + value -= HundredMillion*(uint) div1; + _val2 = FastToDecHex(div1); + } + _val1 = ToDecHex((int) value); + } + + // Translate an unsigned long to hexadecimal digits. + private void InitDecHexDigits(ulong value) + { + if (value >= HundredMillion) + { + long div1 = (long) (value/HundredMillion); + value -= HundredMillion*(ulong) div1; + if (div1 >= HundredMillion) + { + int div2 = (int) (div1/HundredMillion); + div1 = div1 - div2*(long) HundredMillion; + _val3 = ToDecHex(div2); + } + if (div1 != 0) + _val2 = ToDecHex((int) (div1)); + } + if (value != 0) + _val1 = ToDecHex((int) value); + } + + // Translate a decimal integer to hexadecimal digits. + // The decimal integer is 96 digits and its value is hi * 2^64 + lo. + // is the lower 64 bits. + private void InitDecHexDigits(uint hi, ulong lo) + { + if (hi == 0) + { + InitDecHexDigits(lo); // Only the lower 64 bits matter. + return; + } + + // Compute (hi, lo) = (hi , lo) / HundredMillion. + uint divhi = hi/HundredMillion; + ulong remhi = hi - divhi*HundredMillion; + ulong divlo = lo/HundredMillion; + ulong remlo = lo - divlo*HundredMillion + remhi*ULongModHundredMillion; + hi = divhi; + lo = divlo + remhi*ULongDivHundredMillion; + divlo = remlo/HundredMillion; + remlo -= divlo*HundredMillion; + lo += divlo; + _val1 = ToDecHex((int) remlo); + + // Divide hi * 2 ^ 64 + lo by HundredMillion using the fact that + // hi < HundredMillion. + divlo = lo/HundredMillion; + remlo = lo - divlo*HundredMillion; + lo = divlo; + if (hi != 0) + { + lo += hi*ULongDivHundredMillion; + remlo += hi*ULongModHundredMillion; + divlo = remlo/HundredMillion; + lo += divlo; + remlo -= divlo*HundredMillion; + } + _val2 = ToDecHex((int) remlo); + + // Now we are left with 64 bits store in lo. + if (lo >= HundredMillion) + { + divlo = lo/HundredMillion; + lo -= divlo*HundredMillion; + _val4 = ToDecHex((int) divlo); + } + _val3 = ToDecHex((int) lo); + } + + // Helper to translate an int in the range 0 .. 9999 to its + // Hexadecimal digits representation. + private static uint FastToDecHex(int val) + { + if (val < 100) + return (uint) DecHexDigits[val]; + + // Uses 2^19 (524288) to compute val / 100 for val < 10000. + int v = (val*5243) >> 19; + return (uint) ((DecHexDigits[v] << 8) | DecHexDigits[val - v*100]); + } + + // Helper to translate an int in the range 0 .. 99999999 to its + // Hexadecimal digits representation. + private static uint ToDecHex(int val) + { + uint res = 0; + if (val >= 10000) + { + int v = val/10000; + val -= v*10000; + res = FastToDecHex(v) << 16; + } + return res | FastToDecHex(val); + } + + // Helper to count number of hexadecimal digits in a number. + private static int FastDecHexLen(int val) + { + if (val < 0x100) + if (val < 0x10) + return 1; + else + return 2; + else if (val < 0x1000) + return 3; + else + return 4; + } + + private static int DecHexLen(uint val) + { + if (val < 0x10000) + return FastDecHexLen((int) val); + return 4 + FastDecHexLen((int) (val >> 16)); + } + + // Count number of hexadecimal digits stored in _val1 .. _val4. + private int DecHexLen() + { + if (_val4 != 0) + return DecHexLen(_val4) + 24; + else if (_val3 != 0) + return DecHexLen(_val3) + 16; + else if (_val2 != 0) + return DecHexLen(_val2) + 8; + else if (_val1 != 0) + return DecHexLen(_val1); + else + return 0; + } + + // Helper to count the 10th scale (number of digits) in a number + private static int ScaleOrder(long hi) + { + for (int i = TenPowersListLength - 1; i >= 0; i--) + if (hi >= GetTenPowerOf(i)) + return i + 1; + return 1; + } + + // Compute the initial precision for rounding a floating number + // according to the used format. + private int InitialFloatingPrecision() + { + if (_specifier == 'R') + return _defPrecision + 2; + if (_precision < _defPrecision) + return _defPrecision; + if (_specifier == 'G') + return Math.Min(_defPrecision + 2, _precision); + if (_specifier == 'E') + return Math.Min(_defPrecision + 2, _precision + 1); + return _defPrecision; + } + + // Parse the given format and extract the precision in it. + // Returns -1 for empty formats and -2 to indicate that the format + // is a custom format. + private static int ParsePrecision(string format) + { + int precision = 0; + for (int i = 1; i < format.Length; i++) + { + int val = format[i] - '0'; + precision = precision*10 + val; + if (val < 0 || val > 9 || precision > 99) + return -2; + } + return precision; + } + + #endregion Constructor Helpers + + #region Constructors + + // Parse the given format and initialize the following fields: + // _isCustomFormat, _specifierIsUpper, _specifier & _precision. + private NumberFormatter(Thread current) + { + _cbuf = new char[0]; + if (current == null) + return; + CurrentCulture = current.CurrentCulture; + } + + private void Init(string format) + { + _val1 = _val2 = _val3 = _val4 = 0; + _offset = 0; + _NaN = _infinity = false; + _isCustomFormat = false; + _specifierIsUpper = true; + _precision = -1; + + if (format == null || format.Length == 0) + { + _specifier = 'G'; + return; + } + + char specifier = format[0]; + if (specifier >= 'a' && specifier <= 'z') + { + specifier = (char) (specifier - 'a' + 'A'); + _specifierIsUpper = false; + } + else if (specifier < 'A' || specifier > 'Z') + { + _isCustomFormat = true; + _specifier = '0'; + return; + } + _specifier = specifier; + if (format.Length > 1) + { + _precision = ParsePrecision(format); + if (_precision == -2) + { + // Is it a custom format? + _isCustomFormat = true; + _specifier = '0'; + _precision = -1; + } + } + } + + private void InitHex(ulong value) + { + switch (_defPrecision) + { + case Int32DefPrecision: + value = (uint) value; + break; + } + _val1 = (uint) value; + _val2 = (uint) (value >> 32); + _decPointPos = _digitsLen = DecHexLen(); + if (value == 0) + _decPointPos = 1; + } + + private void Init(string format, int value, int defPrecision) + { + Init(format); + _defPrecision = defPrecision; + _positive = value >= 0; + + if (value == 0 || _specifier == 'X') + { + InitHex((ulong) value); + return; + } + + if (value < 0) + value = -value; + InitDecHexDigits((uint) value); + _decPointPos = _digitsLen = DecHexLen(); + } + + private void Init(string format, uint value, int defPrecision) + { + Init(format); + _defPrecision = defPrecision; + _positive = true; + + if (value == 0 || _specifier == 'X') + { + InitHex(value); + return; + } + + InitDecHexDigits(value); + _decPointPos = _digitsLen = DecHexLen(); + } + + private void Init(string format, long value) + { + Init(format); + _defPrecision = Int64DefPrecision; + _positive = value >= 0; + + if (value == 0 || _specifier == 'X') + { + InitHex((ulong) value); + return; + } + + if (value < 0) + value = -value; + InitDecHexDigits((ulong) value); + _decPointPos = _digitsLen = DecHexLen(); + } + + private void Init(string format, ulong value) + { + Init(format); + _defPrecision = UInt64DefPrecision; + _positive = true; + + if (value == 0 || _specifier == 'X') + { + InitHex((ulong) value); + return; + } + + InitDecHexDigits(value); + _decPointPos = _digitsLen = DecHexLen(); + } + + private void Init(string format, double value, int defPrecision) + { + unchecked + { + Init(format); + + _defPrecision = defPrecision; + long bits = BitConverter.DoubleToInt64Bits(value); + _positive = bits >= 0; + bits &= Int64.MaxValue; + if (bits == 0) + { + _decPointPos = 1; + _digitsLen = 0; + _positive = true; + return; + } + + int e = (int) (bits >> DoubleBitsExponentShift); + long m = bits & DoubleBitsMantissaMask; + if (e == DoubleBitsExponentMask) + { + _NaN = m != 0; + _infinity = m == 0; + return; + } + + int expAdjust = 0; + if (e == 0) + { + // We need 'm' to be large enough so we won't lose precision. + e = 1; + int scale = ScaleOrder(m); + if (scale < DoubleDefPrecision) + { + expAdjust = scale - DoubleDefPrecision; + m *= GetTenPowerOf(-expAdjust); + } + } + else + { + m = (m + DoubleBitsMantissaMask + 1)*10; + expAdjust = -1; + } + + // multiply the mantissa by 10 ^ N + ulong lo = (uint) m; + ulong hi = (ulong) m >> 32; + ulong lo2 = MantissaBitsTable[e]; + ulong hi2 = lo2 >> 32; + lo2 = (uint) lo2; + ulong mm = hi*lo2 + lo*hi2 + ((lo*lo2) >> 32); + long res = (long) (hi*hi2 + (mm >> 32)); + while (res < SeventeenDigitsThreshold) + { + mm = (mm & UInt32.MaxValue)*10; + res = res*10 + (long) (mm >> 32); + expAdjust--; + } + if ((mm & 0x80000000) != 0) + res++; + + int order = DoubleDefPrecision + 2; + _decPointPos = TensExponentTable[e] + expAdjust + order; + + // Rescale 'res' to the initial precision (15-17 for doubles). + int initialPrecision = InitialFloatingPrecision(); + if (order > initialPrecision) + { + long val = GetTenPowerOf(order - initialPrecision); + res = (res + (val >> 1))/val; + order = initialPrecision; + } + if (res >= GetTenPowerOf(order)) + { + order++; + _decPointPos++; + } + + InitDecHexDigits((ulong) res); + _offset = CountTrailingZeros(); + _digitsLen = order - _offset; + } + } + + private void Init(string format, decimal value) + { + Init(format); + _defPrecision = DecimalDefPrecision; + + int[] bits = decimal.GetBits(value); + int scale = (bits[3] & DecimalBitsScaleMask) >> 16; + _positive = bits[3] >= 0; + if (bits[0] == 0 && bits[1] == 0 && bits[2] == 0) + { + _decPointPos = -scale; + _positive = true; + _digitsLen = 0; + return; + } + + InitDecHexDigits((uint) bits[2], ((ulong) bits[1] << 32) | (uint) bits[0]); + _digitsLen = DecHexLen(); + _decPointPos = _digitsLen - scale; + if (_precision != -1 || _specifier != 'G') + { + _offset = CountTrailingZeros(); + _digitsLen -= _offset; + } + } + + #endregion Constructors + + #region Inner String Buffer + + //_cbuf moved to before other fields to improve layout + private int _ind; + + private void ResetCharBuf(int size) + { + _ind = 0; + if (_cbuf.Length < size) + _cbuf = new char[size]; + } + + private void Resize(int len) + { + Array.Resize(ref _cbuf, len); + } + + private void Append(char c) + { + if (_ind == _cbuf.Length) + Resize(_ind + 10); + _cbuf[_ind++] = c; + } + + private void Append(char c, int cnt) + { + if (_ind + cnt > _cbuf.Length) + Resize(_ind + cnt + 10); + while (cnt-- > 0) + _cbuf[_ind++] = c; + } + + private void Append(string s) + { + int slen = s.Length; + if (_ind + slen > _cbuf.Length) + Resize(_ind + slen + 10); + for (int i = 0; i < slen; i++) + _cbuf[_ind++] = s[i]; + } + + #endregion Inner String Buffer + + #region Helper properties + + private NumberFormatInfo GetNumberFormatInstance(IFormatProvider fp) + { + if (_nfi != null && fp == null) + return _nfi; + return NumberFormatInfo.GetInstance(fp); + } + + private CultureInfo CurrentCulture + { + set + { + if (value != null && value.IsReadOnly) + _nfi = value.NumberFormat; + else + _nfi = null; + } + } + + private int IntegerDigits + { + get { return _decPointPos > 0 ? _decPointPos : 1; } + } + + private int DecimalDigits + { + get { return _digitsLen > _decPointPos ? _digitsLen - _decPointPos : 0; } + } + + private bool IsFloatingSource + { + get { return _defPrecision == DoubleDefPrecision || _defPrecision == SingleDefPrecision; } + } + + private bool IsZero + { + get { return _digitsLen == 0; } + } + + private bool IsZeroInteger + { + get { return _digitsLen == 0 || _decPointPos <= 0; } + } + + #endregion Helper properties + + #region Round + + private void RoundPos(int pos) + { + RoundBits(_digitsLen - pos); + } + + private bool RoundDecimal(int decimals) + { + return RoundBits(_digitsLen - _decPointPos - decimals); + } + + private bool RoundBits(int shift) + { + if (shift <= 0) + return false; + + if (shift > _digitsLen) + { + _digitsLen = 0; + _decPointPos = 1; + _val1 = _val2 = _val3 = _val4 = 0; + _positive = true; + return false; + } + shift += _offset; + _digitsLen += _offset; + while (shift > 8) + { + _val1 = _val2; + _val2 = _val3; + _val3 = _val4; + _val4 = 0; + _digitsLen -= 8; + shift -= 8; + } + shift = (shift - 1) << 2; + uint v = _val1 >> shift; + uint rem16 = v & 0xf; + _val1 = (v ^ rem16) << shift; + bool res = false; + if (rem16 >= 0x5) + { + _val1 |= 0x99999999 >> (28 - shift); + AddOneToDecHex(); + int newlen = DecHexLen(); + res = newlen != _digitsLen; + _decPointPos = _decPointPos + newlen - _digitsLen; + _digitsLen = newlen; + } + RemoveTrailingZeros(); + return res; + } + + private void RemoveTrailingZeros() + { + _offset = CountTrailingZeros(); + _digitsLen -= _offset; + if (_digitsLen == 0) + { + _offset = 0; + _decPointPos = 1; + _positive = true; + } + } + + private void AddOneToDecHex() + { + if (_val1 == 0x99999999) + { + _val1 = 0; + if (_val2 == 0x99999999) + { + _val2 = 0; + if (_val3 == 0x99999999) + { + _val3 = 0; + _val4 = AddOneToDecHex(_val4); + } + else + _val3 = AddOneToDecHex(_val3); + } + else + _val2 = AddOneToDecHex(_val2); + } + else + _val1 = AddOneToDecHex(_val1); + } + + // Assume val != 0x99999999 + private static uint AddOneToDecHex(uint val) + { + if ((val & 0xffff) == 0x9999) + if ((val & 0xffffff) == 0x999999) + if ((val & 0xfffffff) == 0x9999999) + return val + 0x06666667; + else + return val + 0x00666667; + else if ((val & 0xfffff) == 0x99999) + return val + 0x00066667; + else + return val + 0x00006667; + else if ((val & 0xff) == 0x99) + if ((val & 0xfff) == 0x999) + return val + 0x00000667; + else + return val + 0x00000067; + else if ((val & 0xf) == 0x9) + return val + 0x00000007; + else + return val + 1; + } + + private int CountTrailingZeros() + { + if (_val1 != 0) + return CountTrailingZeros(_val1); + if (_val2 != 0) + return CountTrailingZeros(_val2) + 8; + if (_val3 != 0) + return CountTrailingZeros(_val3) + 16; + if (_val4 != 0) + return CountTrailingZeros(_val4) + 24; + return _digitsLen; + } + + private static int CountTrailingZeros(uint val) + { + if ((val & 0xffff) == 0) + if ((val & 0xffffff) == 0) + if ((val & 0xfffffff) == 0) + return 7; + else + return 6; + else if ((val & 0xfffff) == 0) + return 5; + else + return 4; + else if ((val & 0xff) == 0) + if ((val & 0xfff) == 0) + return 3; + else + return 2; + else if ((val & 0xf) == 0) + return 1; + else + return 0; + } + + #endregion Round + + #region public number formatting methods + + [ThreadStatic] private static NumberFormatter threadNumberFormatter; + + [ThreadStatic] private static NumberFormatter userFormatProvider; + + private static NumberFormatter GetInstance(IFormatProvider fp) + { + if (fp != null) + { + if (userFormatProvider == null) + { + Interlocked.CompareExchange(ref userFormatProvider, new NumberFormatter(null), null); + } + + return userFormatProvider; + } + + NumberFormatter res = threadNumberFormatter; + threadNumberFormatter = null; + if (res == null) + return new NumberFormatter(Thread.CurrentThread); + res.CurrentCulture = Thread.CurrentThread.CurrentCulture; + return res; + } + + private void Release() + { + if (this != userFormatProvider) + threadNumberFormatter = this; + } + + public static string NumberToString(string format, short value, IFormatProvider fp) + { + return NumberToString(format, (int) value, fp); + } + + public static string NumberToString(string format, ushort value, IFormatProvider fp) + { + return NumberToString(format, (int) value, fp); + } + + public static string NumberToString(string format, byte value, IFormatProvider fp) + { + return NumberToString(format, (int)value, fp); + } + public static string NumberToString(string format, sbyte value, IFormatProvider fp) + { + return NumberToString(format, (int)value, fp); + } + + public static string NumberToString(string format, uint value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value, Int32DefPrecision); + string res = inst.IntegerToString(format, fp); + inst.Release(); + return res; + } + + public static string NumberToString(string format, int value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value, UInt32DefPrecision); + string res = inst.IntegerToString(format, fp); + inst.Release(); + return res; + } + + public static string NumberToString(string format, ulong value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value); + string res = inst.IntegerToString(format, fp); + inst.Release(); + return res; + } + + public static string NumberToString(string format, long value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value); + string res = inst.IntegerToString(format, fp); + inst.Release(); + return res; + } + + public static string NumberToString(string format, float value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value, SingleDefPrecision); + NumberFormatInfo nfi = inst.GetNumberFormatInstance(fp); + string res; + if (inst._NaN) + res = nfi.NaNSymbol; + else if (inst._infinity) + if (inst._positive) + res = nfi.PositiveInfinitySymbol; + else + res = nfi.NegativeInfinitySymbol; + else if (inst._specifier == 'R') + res = inst.FormatRoundtrip(value, nfi); + else + res = inst.NumberToString(format, nfi); + inst.Release(); + return res; + } + + public static string NumberToString(string format, double value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value, DoubleDefPrecision); + NumberFormatInfo nfi = inst.GetNumberFormatInstance(fp); + string res; + if (inst._NaN) + res = nfi.NaNSymbol; + else if (inst._infinity) + if (inst._positive) + res = nfi.PositiveInfinitySymbol; + else + res = nfi.NegativeInfinitySymbol; + else if (inst._specifier == 'R') + res = inst.FormatRoundtrip(value, nfi); + else + res = inst.NumberToString(format, nfi); + inst.Release(); + return res; + } + + public static string NumberToString(string format, decimal value, IFormatProvider fp) + { + NumberFormatter inst = GetInstance(fp); + inst.Init(format, value); + string res = inst.NumberToString(format, inst.GetNumberFormatInstance(fp)); + inst.Release(); + return res; + } + + private string IntegerToString(string format, IFormatProvider fp) + { + NumberFormatInfo nfi = GetNumberFormatInstance(fp); + switch (_specifier) + { + case 'C': + return FormatCurrency(_precision, nfi); + case 'D': + return FormatDecimal(_precision, nfi); + case 'E': + return FormatExponential(_precision, nfi); + case 'F': + return FormatFixedPoint(_precision, nfi); + case 'G': + if (_precision <= 0) + return FormatDecimal(-1, nfi); + return FormatGeneral(_precision, nfi); + case 'N': + return FormatNumber(_precision, nfi); + case 'P': + return FormatPercent(_precision, nfi); + case 'X': + return FormatHexadecimal(_precision); + default: + if (_isCustomFormat) + return FormatCustom(format, nfi); + throw new FormatException("The specified format '" + format + "' is invalid"); + } + } + + private string NumberToString(string format, NumberFormatInfo nfi) + { + switch (_specifier) + { + case 'C': + return FormatCurrency(_precision, nfi); + case 'E': + return FormatExponential(_precision, nfi); + case 'F': + return FormatFixedPoint(_precision, nfi); + case 'G': + return FormatGeneral(_precision, nfi); + case 'N': + return FormatNumber(_precision, nfi); + case 'P': + return FormatPercent(_precision, nfi); + case 'X': + default: + if (_isCustomFormat) + return FormatCustom(format, nfi); + throw new FormatException("The specified format '" + format + "' is invalid"); + } + } + + private string FormatCurrency(int precision, NumberFormatInfo nfi) + { + precision = (precision >= 0 ? precision : nfi.CurrencyDecimalDigits); + RoundDecimal(precision); + ResetCharBuf(IntegerDigits*2 + precision*2 + 16); + + if (_positive) + { + switch (nfi.CurrencyPositivePattern) + { + case 0: + Append(nfi.CurrencySymbol); + break; + case 2: + Append(nfi.CurrencySymbol); + Append(' '); + break; + } + } + else + { + switch (nfi.CurrencyNegativePattern) + { + case 0: + Append('('); + Append(nfi.CurrencySymbol); + break; + case 1: + Append(nfi.NegativeSign); + Append(nfi.CurrencySymbol); + break; + case 2: + Append(nfi.CurrencySymbol); + Append(nfi.NegativeSign); + break; + case 3: + Append(nfi.CurrencySymbol); + break; + case 4: + Append('('); + break; + case 5: + Append(nfi.NegativeSign); + break; + case 8: + Append(nfi.NegativeSign); + break; + case 9: + Append(nfi.NegativeSign); + Append(nfi.CurrencySymbol); + Append(' '); + break; + case 11: + Append(nfi.CurrencySymbol); + Append(' '); + break; + case 12: + Append(nfi.CurrencySymbol); + Append(' '); + Append(nfi.NegativeSign); + break; + case 14: + Append('('); + Append(nfi.CurrencySymbol); + Append(' '); + break; + case 15: + Append('('); + break; + } + } + + AppendIntegerStringWithGroupSeparator(nfi.CurrencyGroupSizes, nfi.CurrencyGroupSeparator); + + if (precision > 0) + { + Append(nfi.CurrencyDecimalSeparator); + AppendDecimalString(precision); + } + + if (_positive) + { + switch (nfi.CurrencyPositivePattern) + { + case 1: + Append(nfi.CurrencySymbol); + break; + case 3: + Append(' '); + Append(nfi.CurrencySymbol); + break; + } + } + else + { + switch (nfi.CurrencyNegativePattern) + { + case 0: + Append(')'); + break; + case 3: + Append(nfi.NegativeSign); + break; + case 4: + Append(nfi.CurrencySymbol); + Append(')'); + break; + case 5: + Append(nfi.CurrencySymbol); + break; + case 6: + Append(nfi.NegativeSign); + Append(nfi.CurrencySymbol); + break; + case 7: + Append(nfi.CurrencySymbol); + Append(nfi.NegativeSign); + break; + case 8: + Append(' '); + Append(nfi.CurrencySymbol); + break; + case 10: + Append(' '); + Append(nfi.CurrencySymbol); + Append(nfi.NegativeSign); + break; + case 11: + Append(nfi.NegativeSign); + break; + case 13: + Append(nfi.NegativeSign); + Append(' '); + Append(nfi.CurrencySymbol); + break; + case 14: + Append(')'); + break; + case 15: + Append(' '); + Append(nfi.CurrencySymbol); + Append(')'); + break; + } + } + + return new string(_cbuf, 0, _ind); + } + + private string FormatDecimal(int precision, NumberFormatInfo nfi) + { + if (precision < _digitsLen) + precision = _digitsLen; + if (precision == 0) + return "0"; + + ResetCharBuf(precision + 1); + if (!_positive) + Append(nfi.NegativeSign); + AppendDigits(0, precision); + + return new string(_cbuf, 0, _ind); + } + + private string FormatHexadecimal(int precision) + { + int size = Math.Max(precision, _decPointPos); + char[] digits = _specifierIsUpper ? DigitUpperTable : DigitLowerTable; + + ResetCharBuf(size); + _ind = size; + ulong val = _val1 | ((ulong) _val2 << 32); + while (size > 0) + { + //TODO: Remove (uint) cast and report JSIL bug. + _cbuf[--size] = digits[(uint)(val & 0xf)]; + val >>= 4; + } + return new string(_cbuf, 0, _ind); + } + + private string FormatFixedPoint(int precision, NumberFormatInfo nfi) + { + if (precision == -1) + precision = nfi.NumberDecimalDigits; + + RoundDecimal(precision); + + ResetCharBuf(IntegerDigits + precision + 2); + + if (!_positive) + Append(nfi.NegativeSign); + + AppendIntegerString(IntegerDigits); + + if (precision > 0) + { + Append(nfi.NumberDecimalSeparator); + AppendDecimalString(precision); + } + + return new string(_cbuf, 0, _ind); + } + + private string FormatRoundtrip(double origval, NumberFormatInfo nfi) + { + NumberFormatter nfc = GetClone(); + if (origval >= MinRoundtripVal && origval <= MaxRoundtripVal) + { + string shortRep = FormatGeneral(_defPrecision, nfi); + if (origval == Double.Parse(shortRep, nfi)) + return shortRep; + } + return nfc.FormatGeneral(_defPrecision + 2, nfi); + } + + private string FormatRoundtrip(float origval, NumberFormatInfo nfi) + { + NumberFormatter nfc = GetClone(); + string shortRep = FormatGeneral(_defPrecision, nfi); + // Check roundtrip only for "normal" double values. + if (origval == Single.Parse(shortRep, nfi)) + return shortRep; + return nfc.FormatGeneral(_defPrecision + 2, nfi); + } + + private string FormatGeneral(int precision, NumberFormatInfo nfi) + { + bool enableExp; + if (precision == -1) + { + enableExp = IsFloatingSource; + precision = _defPrecision; + } + else + { + enableExp = true; + if (precision == 0) + precision = _defPrecision; + RoundPos(precision); + } + + int intDigits = _decPointPos; + int digits = _digitsLen; + int decDigits = digits - intDigits; + + if ((intDigits > precision || intDigits <= -4) && enableExp) + return FormatExponential(digits - 1, nfi, 2); + + if (decDigits < 0) + decDigits = 0; + if (intDigits < 0) + intDigits = 0; + ResetCharBuf(decDigits + intDigits + 3); + + if (!_positive) + Append(nfi.NegativeSign); + + if (intDigits == 0) + Append('0'); + else + AppendDigits(digits - intDigits, digits); + + if (decDigits > 0) + { + Append(nfi.NumberDecimalSeparator); + AppendDigits(0, decDigits); + } + + return new string(_cbuf, 0, _ind); + } + + private string FormatNumber(int precision, NumberFormatInfo nfi) + { + precision = (precision >= 0 ? precision : nfi.NumberDecimalDigits); + ResetCharBuf(IntegerDigits*3 + precision); + RoundDecimal(precision); + + if (!_positive) + { + switch (nfi.NumberNegativePattern) + { + case 0: + Append('('); + break; + case 1: + Append(nfi.NegativeSign); + break; + case 2: + Append(nfi.NegativeSign); + Append(' '); + break; + } + } + + AppendIntegerStringWithGroupSeparator(nfi.NumberGroupSizes, nfi.NumberGroupSeparator); + + if (precision > 0) + { + Append(nfi.NumberDecimalSeparator); + AppendDecimalString(precision); + } + + if (!_positive) + { + switch (nfi.NumberNegativePattern) + { + case 0: + Append(')'); + break; + case 3: + Append(nfi.NegativeSign); + break; + case 4: + Append(' '); + Append(nfi.NegativeSign); + break; + } + } + + return new string(_cbuf, 0, _ind); + } + + private string FormatPercent(int precision, NumberFormatInfo nfi) + { + precision = (precision >= 0 ? precision : nfi.PercentDecimalDigits); + Multiply10(2); + RoundDecimal(precision); + ResetCharBuf(IntegerDigits*2 + precision + 16); + + if (_positive) + { + if (nfi.PercentPositivePattern == 2) + Append(nfi.PercentSymbol); + } + else + { + switch (nfi.PercentNegativePattern) + { + case 0: + Append(nfi.NegativeSign); + break; + case 1: + Append(nfi.NegativeSign); + break; + case 2: + Append(nfi.NegativeSign); + Append(nfi.PercentSymbol); + break; + } + } + + AppendIntegerStringWithGroupSeparator(nfi.PercentGroupSizes, nfi.PercentGroupSeparator); + + if (precision > 0) + { + Append(nfi.PercentDecimalSeparator); + AppendDecimalString(precision); + } + + if (_positive) + { + switch (nfi.PercentPositivePattern) + { + case 0: + Append(' '); + Append(nfi.PercentSymbol); + break; + case 1: + Append(nfi.PercentSymbol); + break; + } + } + else + { + switch (nfi.PercentNegativePattern) + { + case 0: + Append(' '); + Append(nfi.PercentSymbol); + break; + case 1: + Append(nfi.PercentSymbol); + break; + } + } + + return new string(_cbuf, 0, _ind); + } + + private string FormatExponential(int precision, NumberFormatInfo nfi) + { + if (precision == -1) + precision = DefaultExpPrecision; + + RoundPos(precision + 1); + return FormatExponential(precision, nfi, 3); + } + + private string FormatExponential(int precision, NumberFormatInfo nfi, int expDigits) + { + int decDigits = _decPointPos; + int digits = _digitsLen; + int exponent = decDigits - 1; + decDigits = _decPointPos = 1; + + ResetCharBuf(precision + 8); + + if (!_positive) + Append(nfi.NegativeSign); + + AppendOneDigit(digits - 1); + + if (precision > 0) + { + Append(nfi.NumberDecimalSeparator); + AppendDigits(digits - precision - 1, digits - _decPointPos); + } + + AppendExponent(nfi, exponent, expDigits); + + return new string(_cbuf, 0, _ind); + } + + private string FormatCustom(string format, NumberFormatInfo nfi) + { + bool p = _positive; + int offset = 0; + int length = 0; + CustomInfo.GetActiveSection(format, ref p, IsZero, ref offset, ref length); + if (length == 0) + return _positive ? string.Empty : nfi.NegativeSign; + _positive = p; + + CustomInfo info = CustomInfo.Parse(format, offset, length, nfi); +#if false + Console.WriteLine ("Format : {0}",format); + Console.WriteLine ("DecimalDigits : {0}",info.DecimalDigits); + Console.WriteLine ("DecimalPointPos : {0}",info.DecimalPointPos); + Console.WriteLine ("DecimalTailSharpDigits : {0}",info.DecimalTailSharpDigits); + Console.WriteLine ("IntegerDigits : {0}",info.IntegerDigits); + Console.WriteLine ("IntegerHeadSharpDigits : {0}",info.IntegerHeadSharpDigits); + Console.WriteLine ("IntegerHeadPos : {0}",info.IntegerHeadPos); + Console.WriteLine ("UseExponent : {0}",info.UseExponent); + Console.WriteLine ("ExponentDigits : {0}",info.ExponentDigits); + Console.WriteLine ("ExponentTailSharpDigits : {0}",info.ExponentTailSharpDigits); + Console.WriteLine ("ExponentNegativeSignOnly : {0}",info.ExponentNegativeSignOnly); + Console.WriteLine ("DividePlaces : {0}",info.DividePlaces); + Console.WriteLine ("Percents : {0}",info.Percents); + Console.WriteLine ("Permilles : {0}",info.Permilles); +#endif + StringBuilder sb_int = new StringBuilder(info.IntegerDigits*2); + StringBuilder sb_dec = new StringBuilder(info.DecimalDigits*2); + StringBuilder sb_exp = (info.UseExponent ? new StringBuilder(info.ExponentDigits*2) : null); + + int diff = 0; + if (info.Percents > 0) + Multiply10(2*info.Percents); + if (info.Permilles > 0) + Multiply10(3*info.Permilles); + if (info.DividePlaces > 0) + Divide10(info.DividePlaces); + + bool expPositive = true; + if (info.UseExponent && (info.DecimalDigits > 0 || info.IntegerDigits > 0)) + { + if (!IsZero) + { + RoundPos(info.DecimalDigits + info.IntegerDigits); + diff -= _decPointPos - info.IntegerDigits; + _decPointPos = info.IntegerDigits; + } + + expPositive = diff <= 0; + AppendNonNegativeNumber(sb_exp, diff < 0 ? -diff : diff); + } + else + RoundDecimal(info.DecimalDigits); + + if (info.IntegerDigits != 0 || !IsZeroInteger) + AppendIntegerString(IntegerDigits, sb_int); + + AppendDecimalString(DecimalDigits, sb_dec); + + if (info.UseExponent) + { + if (info.DecimalDigits <= 0 && info.IntegerDigits <= 0) + _positive = true; + + if (sb_int.Length < info.IntegerDigits) + sb_int.Insert(0, "0", info.IntegerDigits - sb_int.Length); + + while (sb_exp.Length < info.ExponentDigits - info.ExponentTailSharpDigits) + sb_exp.Insert(0, '0'); + + if (expPositive && !info.ExponentNegativeSignOnly) + sb_exp.Insert(0, nfi.PositiveSign); + else if (!expPositive) + sb_exp.Insert(0, nfi.NegativeSign); + } + else + { + if (sb_int.Length < info.IntegerDigits - info.IntegerHeadSharpDigits) + sb_int.Insert(0, "0", info.IntegerDigits - info.IntegerHeadSharpDigits - sb_int.Length); + if (info.IntegerDigits == info.IntegerHeadSharpDigits && IsZeroOnly(sb_int)) + sb_int.Remove(0, sb_int.Length); + } + + ZeroTrimEnd(sb_dec, true); + while (sb_dec.Length < info.DecimalDigits - info.DecimalTailSharpDigits) + sb_dec.Append('0'); + if (sb_dec.Length > info.DecimalDigits) + sb_dec.Remove(info.DecimalDigits, sb_dec.Length - info.DecimalDigits); + + return info.Format(format, offset, length, nfi, _positive, sb_int, sb_dec, sb_exp); + } + + #endregion public number formatting methods + + #region StringBuilder formatting helpers + + private static void ZeroTrimEnd(StringBuilder sb, bool canEmpty) + { + int len = 0; + for (int i = sb.Length - 1; (canEmpty ? i >= 0 : i > 0); i--) + { + if (sb[i] != '0') + break; + len++; + } + + if (len > 0) + sb.Remove(sb.Length - len, len); + } + + private static bool IsZeroOnly(StringBuilder sb) + { + for (int i = 0; i < sb.Length; i++) + if (char.IsDigit(sb[i]) && sb[i] != '0') + return false; + return true; + } + + private static void AppendNonNegativeNumber(StringBuilder sb, int v) + { + if (v < 0) + throw new ArgumentException(); + + int i = ScaleOrder(v) - 1; + do + { + int n = v/(int) GetTenPowerOf(i); + sb.Append((char) ('0' | n)); + v -= (int) GetTenPowerOf(i--)*n; + } while (i >= 0); + } + + #endregion StringBuilder formatting helpers + + #region Append helpers + + private void AppendIntegerString(int minLength, StringBuilder sb) + { + if (_decPointPos <= 0) + { + sb.Append('0', minLength); + return; + } + + if (_decPointPos < minLength) + sb.Append('0', minLength - _decPointPos); + + AppendDigits(_digitsLen - _decPointPos, _digitsLen, sb); + } + + private void AppendIntegerString(int minLength) + { + if (_decPointPos <= 0) + { + Append('0', minLength); + return; + } + + if (_decPointPos < minLength) + Append('0', minLength - _decPointPos); + + AppendDigits(_digitsLen - _decPointPos, _digitsLen); + } + + private void AppendDecimalString(int precision, StringBuilder sb) + { + AppendDigits(_digitsLen - precision - _decPointPos, _digitsLen - _decPointPos, sb); + } + + private void AppendDecimalString(int precision) + { + AppendDigits(_digitsLen - precision - _decPointPos, _digitsLen - _decPointPos); + } + + private void AppendIntegerStringWithGroupSeparator(int[] groups, string groupSeparator) + { + if (IsZeroInteger) + { + Append('0'); + return; + } + + int total = 0; + int groupIndex = 0; + for (int i = 0; i < groups.Length; i++) + { + total += groups[i]; + if (total <= _decPointPos) + groupIndex = i; + else + break; + } + + if (groups.Length > 0 && total > 0) + { + int counter; + int groupSize = groups[groupIndex]; + int fraction = _decPointPos > total ? _decPointPos - total : 0; + if (groupSize == 0) + { + while (groupIndex >= 0 && groups[groupIndex] == 0) + groupIndex--; + + groupSize = fraction > 0 ? fraction : groups[groupIndex]; + } + if (fraction == 0) + counter = groupSize; + else + { + groupIndex += fraction/groupSize; + counter = fraction%groupSize; + if (counter == 0) + counter = groupSize; + else + groupIndex++; + } + + if (total >= _decPointPos) + { + int lastGroupSize = groups[0]; + if (total > lastGroupSize) + { + int lastGroupDiff = -(lastGroupSize - _decPointPos); + int lastGroupMod; + + if (lastGroupDiff < lastGroupSize) + counter = lastGroupDiff; + else if (lastGroupSize > 0 && (lastGroupMod = _decPointPos%lastGroupSize) > 0) + counter = lastGroupMod; + } + } + + for (int i = 0;;) + { + if ((_decPointPos - i) <= counter || counter == 0) + { + AppendDigits(_digitsLen - _decPointPos, _digitsLen - i); + break; + } + AppendDigits(_digitsLen - i - counter, _digitsLen - i); + i += counter; + Append(groupSeparator); + if (--groupIndex < groups.Length && groupIndex >= 0) + groupSize = groups[groupIndex]; + counter = groupSize; + } + } + else + { + AppendDigits(_digitsLen - _decPointPos, _digitsLen); + } + } + + // minDigits is in the range 1..3 + private void AppendExponent(NumberFormatInfo nfi, int exponent, int minDigits) + { + if (_specifierIsUpper || _specifier == 'R') + Append('E'); + else + Append('e'); + + if (exponent >= 0) + Append(nfi.PositiveSign); + else + { + Append(nfi.NegativeSign); + exponent = -exponent; + } + + if (exponent == 0) + Append('0', minDigits); + else if (exponent < 10) + { + Append('0', minDigits - 1); + Append((char) ('0' | exponent)); + } + else + { + uint hexDigit = FastToDecHex(exponent); + if (exponent >= 100 || minDigits == 3) + Append((char) ('0' | (hexDigit >> 8))); + Append((char) ('0' | ((hexDigit >> 4) & 0xf))); + Append((char) ('0' | (hexDigit & 0xf))); + } + } + + private void AppendOneDigit(int start) + { + if (_ind == _cbuf.Length) + Resize(_ind + 10); + + start += _offset; + uint v; + if (start < 0) + v = 0; + else if (start < 8) + v = _val1; + else if (start < 16) + v = _val2; + else if (start < 24) + v = _val3; + else if (start < 32) + v = _val4; + else + v = 0; + v >>= (start & 0x7) << 2; + _cbuf[_ind++] = (char) ('0' | v & 0xf); + } + + private void AppendDigits(int start, int end) + { + if (start >= end) + return; + + int i = _ind + (end - start); + if (i > _cbuf.Length) + Resize(i + 10); + _ind = i; + + end += _offset; + start += _offset; + + for (int next = start + 8 - (start & 0x7);; start = next, next += 8) + { + uint v; + if (next == 8) + v = _val1; + else if (next == 16) + v = _val2; + else if (next == 24) + v = _val3; + else if (next == 32) + v = _val4; + else + v = 0; + v >>= (start & 0x7) << 2; + if (next > end) + next = end; + + _cbuf[--i] = (char) ('0' | v & 0xf); + switch (next - start) + { + case 8: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 7; + case 7: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 6; + case 6: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 5; + case 5: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 4; + case 4: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 3; + case 3: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 2; + case 2: + _cbuf[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 1; + case 1: + if (next == end) + return; + continue; + } + } + } + + private void AppendDigits(int start, int end, StringBuilder sb) + { + if (start >= end) + return; + + int i = sb.Length + (end - start); + sb.Length = i; + + end += _offset; + start += _offset; + + for (int next = start + 8 - (start & 0x7);; start = next, next += 8) + { + uint v; + if (next == 8) + v = _val1; + else if (next == 16) + v = _val2; + else if (next == 24) + v = _val3; + else if (next == 32) + v = _val4; + else + v = 0; + v >>= (start & 0x7) << 2; + if (next > end) + next = end; + sb[--i] = (char) ('0' | v & 0xf); + switch (next - start) + { + case 8: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 7; + case 7: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 6; + case 6: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 5; + case 5: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 4; + case 4: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 3; + case 3: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 2; + case 2: + sb[--i] = (char) ('0' | (v >>= 4) & 0xf); + goto case 1; + case 1: + if (next == end) + return; + continue; + } + } + } + + #endregion Append helpers + + #region others + + private void Multiply10(int count) + { + if (count <= 0 || _digitsLen == 0) + return; + + _decPointPos += count; + } + + private void Divide10(int count) + { + if (count <= 0 || _digitsLen == 0) + return; + + _decPointPos -= count; + } + + private NumberFormatter GetClone() + { + return (NumberFormatter) this.MemberwiseClone(); + } + + #endregion others + + #region custom + + private class CustomInfo + { + public bool UseGroup = false; + public int DecimalDigits = 0; + public int DecimalPointPos = -1; + public int DecimalTailSharpDigits = 0; + public int IntegerDigits = 0; + public int IntegerHeadSharpDigits = 0; + public int IntegerHeadPos = 0; + public bool UseExponent = false; + public int ExponentDigits = 0; + public int ExponentTailSharpDigits = 0; + public bool ExponentNegativeSignOnly = true; + public int DividePlaces = 0; + public int Percents = 0; + public int Permilles = 0; + + public static void GetActiveSection(string format, ref bool positive, bool zero, ref int offset, + ref int length) + { + int[] lens = new int[3]; + int index = 0; + int lastPos = 0; + bool quoted = false; + + for (int i = 0; i < format.Length; i++) + { + char c = format[i]; + + if (c == '\"' || c == '\'') + { + if (i == 0 || format[i - 1] != '\\') + quoted = !quoted; + + continue; + } + + if (c == ';' && !quoted && (i == 0 || format[i - 1] != '\\')) + { + lens[index++] = i - lastPos; + lastPos = i + 1; + if (index == 3) + break; + } + } + + if (index == 0) + { + offset = 0; + length = format.Length; + return; + } + if (index == 1) + { + if (positive || zero) + { + offset = 0; + length = lens[0]; + return; + } + if (lens[0] + 1 < format.Length) + { + positive = true; + offset = lens[0] + 1; + length = format.Length - offset; + return; + } + else + { + offset = 0; + length = lens[0]; + return; + } + } + if (index == 2) + { + if (zero) + { + offset = lens[0] + lens[1] + 2; + length = format.Length - offset; + return; + } + if (positive) + { + offset = 0; + length = lens[0]; + return; + } + if (lens[1] > 0) + { + positive = true; + offset = lens[0] + 1; + length = lens[1]; + return; + } + else + { + offset = 0; + length = lens[0]; + return; + } + } + if (index == 3) + { + if (zero) + { + offset = lens[0] + lens[1] + 2; + length = lens[2]; + return; + } + if (positive) + { + offset = 0; + length = lens[0]; + return; + } + if (lens[1] > 0) + { + positive = true; + offset = lens[0] + 1; + length = lens[1]; + return; + } + else + { + offset = 0; + length = lens[0]; + return; + } + } + + throw new ArgumentException(); + } + + public static CustomInfo Parse(string format, int offset, int length, NumberFormatInfo nfi) + { + char literal = '\0'; + bool integerArea = true; + bool decimalArea = false; + bool exponentArea = false; + bool sharpContinues = true; + + CustomInfo info = new CustomInfo(); + int groupSeparatorCounter = 0; + + for (int i = offset; i - offset < length; i++) + { + char c = format[i]; + + if (c == literal && c != '\0') + { + literal = '\0'; + continue; + } + if (literal != '\0') + continue; + + if (exponentArea && (c != '\0' && c != '0' && c != '#')) + { + exponentArea = false; + integerArea = (info.DecimalPointPos < 0); + decimalArea = !integerArea; + i--; + continue; + } + + switch (c) + { + case '\\': + i++; + continue; + case '\'': + case '\"': + if (c == '\"' || c == '\'') + { + literal = c; + } + continue; + case '#': + if (sharpContinues && integerArea) + info.IntegerHeadSharpDigits++; + else if (decimalArea) + info.DecimalTailSharpDigits++; + else if (exponentArea) + info.ExponentTailSharpDigits++; + + goto case '0'; + case '0': + if (c != '#') + { + sharpContinues = false; + if (decimalArea) + info.DecimalTailSharpDigits = 0; + else if (exponentArea) + info.ExponentTailSharpDigits = 0; + } + if (info.IntegerHeadPos == -1) + info.IntegerHeadPos = i; + + if (integerArea) + { + info.IntegerDigits++; + if (groupSeparatorCounter > 0) + info.UseGroup = true; + groupSeparatorCounter = 0; + } + else if (decimalArea) + info.DecimalDigits++; + else if (exponentArea) + info.ExponentDigits++; + break; + case 'e': + case 'E': + if (info.UseExponent) + break; + + info.UseExponent = true; + integerArea = false; + decimalArea = false; + exponentArea = true; + if (i + 1 - offset < length) + { + char nc = format[i + 1]; + if (nc == '+') + info.ExponentNegativeSignOnly = false; + if (nc == '+' || nc == '-') + i++; + else if (nc != '0' && nc != '#') + { + info.UseExponent = false; + if (info.DecimalPointPos < 0) + integerArea = true; + } + } + + break; + case '.': + integerArea = false; + decimalArea = true; + exponentArea = false; + if (info.DecimalPointPos == -1) + info.DecimalPointPos = i; + break; + case '%': + info.Percents++; + break; + case '\u2030': + info.Permilles++; + break; + case ',': + if (integerArea && info.IntegerDigits > 0) + groupSeparatorCounter++; + break; + default: + break; + } + } + + if (info.ExponentDigits == 0) + info.UseExponent = false; + else + info.IntegerHeadSharpDigits = 0; + + if (info.DecimalDigits == 0) + info.DecimalPointPos = -1; + + info.DividePlaces += groupSeparatorCounter*3; + + return info; + } + + public string Format(string format, int offset, int length, NumberFormatInfo nfi, bool positive, + StringBuilder sb_int, StringBuilder sb_dec, StringBuilder sb_exp) + { + StringBuilder sb = new StringBuilder(); + char literal = '\0'; + bool integerArea = true; + bool decimalArea = false; + int intSharpCounter = 0; + int sb_int_index = 0; + int sb_dec_index = 0; + + int[] groups = nfi.NumberGroupSizes; + string groupSeparator = nfi.NumberGroupSeparator; + int intLen = 0, total = 0, groupIndex = 0, counter = 0, groupSize = 0; + if (UseGroup && groups.Length > 0) + { + intLen = sb_int.Length; + for (int i = 0; i < groups.Length; i++) + { + total += groups[i]; + if (total <= intLen) + groupIndex = i; + } + groupSize = groups[groupIndex]; + int fraction = intLen > total ? intLen - total : 0; + if (groupSize == 0) + { + while (groupIndex >= 0 && groups[groupIndex] == 0) + groupIndex--; + + groupSize = fraction > 0 ? fraction : groups[groupIndex]; + } + if (fraction == 0) + counter = groupSize; + else + { + groupIndex += fraction/groupSize; + counter = fraction%groupSize; + if (counter == 0) + counter = groupSize; + else + groupIndex++; + } + } + else + UseGroup = false; + + for (int i = offset; i - offset < length; i++) + { + char c = format[i]; + + if (c == literal && c != '\0') + { + literal = '\0'; + continue; + } + if (literal != '\0') + { + sb.Append(c); + continue; + } + + switch (c) + { + case '\\': + i++; + if (i - offset < length) + sb.Append(format[i]); + continue; + case '\'': + case '\"': + if (c == '\"' || c == '\'') + literal = c; + continue; + case '#': + goto case '0'; + case '0': + if (integerArea) + { + intSharpCounter++; + if (IntegerDigits - intSharpCounter < sb_int.Length + sb_int_index || c == '0') + while (IntegerDigits - intSharpCounter + sb_int_index < sb_int.Length) + { + sb.Append(sb_int[sb_int_index++]); + if (UseGroup && --intLen > 0 && --counter == 0) + { + sb.Append(groupSeparator); + if (--groupIndex < groups.Length && groupIndex >= 0) + groupSize = groups[groupIndex]; + counter = groupSize; + } + } + break; + } + else if (decimalArea) + { + if (sb_dec_index < sb_dec.Length) + sb.Append(sb_dec[sb_dec_index++]); + break; + } + + sb.Append(c); + break; + case 'e': + case 'E': + if (sb_exp == null || !UseExponent) + { + sb.Append(c); + break; + } + + bool flag1 = true; + bool flag2 = false; + + int q; + for (q = i + 1; q - offset < length; q++) + { + if (format[q] == '0') + { + flag2 = true; + continue; + } + if (q == i + 1 && (format[q] == '+' || format[q] == '-')) + continue; + if (!flag2) + flag1 = false; + break; + } + + if (flag1) + { + i = q - 1; + integerArea = (DecimalPointPos < 0); + decimalArea = !integerArea; + + sb.Append(c); + sb.Append(sb_exp); + sb_exp = null; + } + else + sb.Append(c); + + break; + case '.': + if (DecimalPointPos == i) + { + if (DecimalDigits > 0) + { + while (sb_int_index < sb_int.Length) + sb.Append(sb_int[sb_int_index++]); + } + if (sb_dec.Length > 0) + sb.Append(nfi.NumberDecimalSeparator); + } + integerArea = false; + decimalArea = true; + break; + case ',': + break; + case '%': + sb.Append(nfi.PercentSymbol); + break; + case '\u2030': + sb.Append(nfi.PerMilleSymbol); + break; + default: + sb.Append(c); + break; + } + } + + if (!positive) + sb.Insert(0, nfi.NegativeSign); + + return sb.ToString(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/JSIL.mscorlib/Properties/AssemblyInfo.cs b/JSIL.mscorlib/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..bc05ff917 --- /dev/null +++ b/JSIL.mscorlib/Properties/AssemblyInfo.cs @@ -0,0 +1,39 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using JSIL.Meta; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("JSIL.mscorlib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("JSIL.mscorlib")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("aef2633e-e92c-4a0d-b8e0-a072ed404af7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: JSRepaceAssemblyDeclaration("$jsilcore")] +[assembly: JSOverrideAssemblyReference(typeof(object), "$jsilcore")] \ No newline at end of file diff --git a/JSIL.sln b/JSIL.sln index 11216debd..56955bbc0 100644 --- a/JSIL.sln +++ b/JSIL.sln @@ -60,6 +60,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSIL.Libraries", "JSIL.Libr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compiler.Executor.32bit", "Compiler\Compiler.Executor.32bit.csproj", "{722B0939-1429-4847-AEF4-725AC4F12067}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependecies", "Dependecies", "{C48B5E47-5949-4A0C-87BA-3D151732970A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F70F534D-9AD5-40A0-8241-0EAFBF764266}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{29349860-2CF6-46A9-B0C7-CCD5C3261993}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSIL.mscorlib", "JSIL.mscorlib\JSIL.mscorlib.csproj", "{AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -240,8 +248,31 @@ Global {722B0939-1429-4847-AEF4-725AC4F12067}.Release|Any CPU.Build.0 = Release|x86 {722B0939-1429-4847-AEF4-725AC4F12067}.Release|NoXNA.ActiveCfg = Release|x86 {722B0939-1429-4847-AEF4-725AC4F12067}.Release|NoXNA.Build.0 = Release|x86 + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Debug|NoXNA.ActiveCfg = Debug|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Debug|NoXNA.Build.0 = Debug|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Release|Any CPU.Build.0 = Release|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Release|NoXNA.ActiveCfg = Release|Any CPU + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7}.Release|NoXNA.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {984CC812-9470-4A13-AFF9-CC44068D666C} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {2DBBCB24-54AD-4C66-B7D6-911811CEB185} = {F70F534D-9AD5-40A0-8241-0EAFBF764266} + {2DBBCB24-54AD-4C66-B7D6-911811CEB186} = {F70F534D-9AD5-40A0-8241-0EAFBF764266} + {63E6915C-7EA4-4D76-AB28-0D7191EEA626} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {53DCA265-3C3C-42F9-B647-F72BA678122B} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {10D0D83E-59A8-421C-9C83-3108074B1A9C} = {C48B5E47-5949-4A0C-87BA-3D151732970A} + {B6269EA3-19B6-4684-AD1F-03562FD4AC55} = {29349860-2CF6-46A9-B0C7-CCD5C3261993} + {7B80860D-B937-44E9-B863-7A5E888429E5} = {F70F534D-9AD5-40A0-8241-0EAFBF764266} + {B921F386-44A2-4170-9CB7-18467AF9B7B1} = {29349860-2CF6-46A9-B0C7-CCD5C3261993} + {AEF2633E-E92C-4A0D-B8E0-A072ED404AF7} = {29349860-2CF6-46A9-B0C7-CCD5C3261993} + EndGlobalSection EndGlobal diff --git a/JSIL/AssemblyTranslator.cs b/JSIL/AssemblyTranslator.cs index c554749b6..56b7227fc 100644 --- a/JSIL/AssemblyTranslator.cs +++ b/JSIL/AssemblyTranslator.cs @@ -109,24 +109,6 @@ public MethodToAnalyze (MethodInfo mi) { protected bool OwnsAssemblyDataResolver; protected bool OwnsTypeInfoProvider; - protected readonly static HashSet TypeDeclarationsToSuppress = new HashSet { - "System.Object", "System.ValueType", - "System.Type", "System.Reflection.TypeInfo", "System.RuntimeType", - "System.Reflection.MemberInfo", "System.Reflection.MethodBase", - "System.Reflection.MethodInfo", "System.Reflection.FieldInfo", - "System.Reflection.ConstructorInfo", "System.Reflection.PropertyInfo", "System.Reflection.EventInfo", - "System.Array", "System.Delegate", "System.MulticastDelegate", - "System.Byte", "System.SByte", - "System.UInt16", "System.Int16", - "System.UInt32", "System.Int32", - "System.UInt64", "System.Int64", - "System.Single", "System.Double", - "System.Boolean", "System.Char", - "System.Reflection.Assembly", "System.Reflection.RuntimeAssembly", - "System.Attribute", "System.Decimal", - "System.IntPtr", "System.UIntPtr" - }; - public AssemblyTranslator ( Configuration configuration, TypeInfoProvider typeInfoProvider = null, @@ -843,11 +825,19 @@ private void GetMethodsToAnalyze (AssemblyDefinition assembly, ConcurrentBag item.Resolve())); + } + } return typeList; + } IEnumerable methods = type.Methods; - var typeInfo = TypeInfoProvider.GetExisting(type); if (typeInfo != null) { if (typeInfo.StaticConstructor != null) { @@ -921,11 +911,28 @@ protected void TranslateSingleAssemblyInternal (DecompilerContext context, Assem bool stubbed = IsStubbed(assembly); var tw = new StreamWriter(outputStream, Encoding.ASCII); + + string assemblyDeclarationReplacement = null; + var metadata = new MetadataCollection(assembly); + if (metadata.HasAttribute("JSIL.Meta.JSRepaceAssemblyDeclaration")) + { + assemblyDeclarationReplacement = (string) metadata.GetAttributeParameters("JSIL.Meta.JSRepaceAssemblyDeclaration")[0].Value; + } + + var overrides = + assembly.CustomAttributes.Where( + item => item.AttributeType.FullName == "JSIL.Meta.JSOverrideAssemblyReference") + .ToDictionary( + item => + Manifest.GetPrivateToken( + ((TypeReference) (item.ConstructorArguments[0].Value)).Resolve().Module.Assembly), + item => (string) (item.ConstructorArguments[1].Value)); + var formatter = new JavascriptFormatter( - tw, sourceMapBuilder, this.TypeInfoProvider, Manifest, assembly, Configuration, stubbed + tw, sourceMapBuilder, this.TypeInfoProvider, Manifest, assembly, Configuration, assemblyDeclarationReplacement, stubbed ); - var assemblyEmitter = EmitterFactory.MakeAssemblyEmitter(this, assembly, formatter); + var assemblyEmitter = EmitterFactory.MakeAssemblyEmitter(this, assembly, formatter, overrides.Count > 0 ? overrides : null); assemblyEmitter.EmitHeader(stubbed); @@ -944,6 +951,8 @@ protected void TranslateSingleAssemblyInternal (DecompilerContext context, Assem TranslateModule(context, assemblyEmitter, module, sealedTypes, declaredTypes, stubbed); } + TranslateImportedTypes(assembly, assemblyEmitter, declaredTypes, stubbed); + assemblyEmitter.EmitFooter(); tw.Flush(); @@ -967,6 +976,49 @@ AssemblyDefinition assembly ); } + protected void TranslateImportedTypes(AssemblyDefinition assembly, IAssemblyEmitter assemblyEmitter, + HashSet declaredTypes, bool stubbed) + { + var typesToImport = assembly + .Modules + .SelectMany(item => item.Types) + .Select(type => TypeInfoProvider.GetTypeInformation(type)) + .Where(item => item.IsProxy && item.Metadata.HasAttribute("JSIL.Meta.JSImportType")) + .Select(item => TypeInfoProvider.FindTypeProxy(new TypeIdentifier(item.Definition))) + .SelectMany(item => item.ProxiedTypes) + .Select(item => item.Resolve()) + .GroupBy(item => item.Module) + .GroupBy(item => item.Key.Assembly).ToList(); + + if (typesToImport.Count == 0) + { + return; + } + + foreach (var byAssembly in typesToImport) + { + var context = MakeDecompilerContext(byAssembly.Key.MainModule); + foreach (var byModule in byAssembly) + { + context.CurrentModule = byModule.Key; + + var js = new JSSpecialIdentifiers(FunctionCache.MethodTypes, context.CurrentModule.TypeSystem); + var jsil = new JSILIdentifier(FunctionCache.MethodTypes, context.CurrentModule.TypeSystem, + this.TypeInfoProvider, js); + + var astEmitter = assemblyEmitter.MakeAstEmitter( + jsil, context.CurrentModule.TypeSystem, + TypeInfoProvider, Configuration + ); + + foreach (var typeDefinition in byModule) + { + DeclareType(context, typeDefinition, astEmitter, assemblyEmitter, declaredTypes, stubbed, true); + } + } + } + } + protected void TranslateModule ( DecompilerContext context, IAssemblyEmitter assemblyEmitter, ModuleDefinition module, HashSet sealedTypes, HashSet declaredTypes, bool stubbed @@ -989,13 +1041,6 @@ protected void TranslateModule ( DeclareType(context, typedef, astEmitter, assemblyEmitter, declaredTypes, stubbed); } - protected virtual bool ShouldGenerateTypeDeclaration (TypeDefinition typedef) { - if (TypeDeclarationsToSuppress.Contains(typedef.FullName)) - return false; - - return true; - } - public bool ShouldSkipMember (MemberReference member) { if (member is MethodReference && member.Name == ".cctor") return false; @@ -1010,7 +1055,7 @@ public bool ShouldSkipMember (MemberReference member) { protected void DeclareType ( DecompilerContext context, TypeDefinition typedef, IAstEmitter astEmitter, IAssemblyEmitter assemblyEmitter, - HashSet declaredTypes, bool stubbed + HashSet declaredTypes, bool stubbed, bool isImported = false ) { var typeInfo = TypeInfoProvider.GetTypeInformation(typedef); if ((typeInfo == null) || typeInfo.IsIgnored || typeInfo.IsProxy) @@ -1028,13 +1073,13 @@ protected void DeclareType ( bool declareOnlyInternalTypes = ShouldSkipMember(typedef); // This type is defined in JSIL.Core so we don't want to cause a name collision. - if (!declareOnlyInternalTypes && !ShouldGenerateTypeDeclaration(typedef)) { + if (!declareOnlyInternalTypes && typeInfo.IsSuppressDeclaration && !isImported) { assemblyEmitter.EmitTypeAlias(typedef); declareOnlyInternalTypes = true; } - if (declareOnlyInternalTypes) { + if (declareOnlyInternalTypes && !isImported) { DeclareNestedTypes( context, typedef, astEmitter, assemblyEmitter, @@ -1051,7 +1096,7 @@ protected void DeclareType ( try { // type has a JS replacement, we can't correctly emit a stub or definition for it. // We do want to process nested types, though. - if (typeInfo.Replacement != null) { + if (typeInfo.Replacement != null && !isImported) { DeclareNestedTypes( context, typedef, astEmitter, assemblyEmitter, @@ -1065,7 +1110,7 @@ protected void DeclareType ( return; var declaringType = typedef.DeclaringType; - if (declaringType != null) + if (declaringType != null && !isImported) DeclareType(context, declaringType, astEmitter, assemblyEmitter, declaredTypes, IsStubbed(declaringType.Module.Assembly)); var baseClass = typedef.BaseType; @@ -1074,6 +1119,7 @@ protected void DeclareType ( if ( (resolved != null) && (resolved.Module.Assembly == typedef.Module.Assembly) + && !isImported ) { DeclareType(context, resolved, astEmitter, assemblyEmitter, declaredTypes, IsStubbed(resolved.Module.Assembly)); } @@ -1102,8 +1148,11 @@ protected void DeclareType ( assemblyEmitter.EndEmitTypeDefinition(astEmitter, context, typedef); } - foreach (var nestedTypeDef in typedef.NestedTypes) - DeclareType(context, nestedTypeDef, astEmitter, assemblyEmitter, declaredTypes, stubbed); + if (!isImported) + { + foreach (var nestedTypeDef in typedef.NestedTypes) + DeclareType(context, nestedTypeDef, astEmitter, assemblyEmitter, declaredTypes, stubbed); + } } catch (Exception exc) { throw new Exception(String.Format("An error occurred while declaring the type '{0}'", typedef.FullName), exc); } finally { @@ -1955,7 +2004,7 @@ out bool methodIsProxied methodIsProxied = (methodInfo.IsFromProxy && methodInfo.Member.HasBody) && !methodInfo.IsExternal && !isJSReplaced; - isExternal = methodInfo.IsExternal || (stubbed && !methodIsProxied && !methodInfo.IsUnstubbable); + isExternal = methodInfo.IsExternal || (stubbed && !methodInfo.IsUnstubbable); } internal bool ShouldTranslateMethodBody ( @@ -2138,10 +2187,11 @@ public string FileExtension { public IAssemblyEmitter MakeAssemblyEmitter ( AssemblyTranslator assemblyTranslator, AssemblyDefinition assembly, - JavascriptFormatter formatter + JavascriptFormatter formatter, + IDictionary referenceOverrides ) { return new JavascriptAssemblyEmitter( - assemblyTranslator, formatter + assemblyTranslator, formatter, referenceOverrides ); } diff --git a/JSIL/Extensibility/Emitter.cs b/JSIL/Extensibility/Emitter.cs index 06d3ac5b7..ef96b2930 100644 --- a/JSIL/Extensibility/Emitter.cs +++ b/JSIL/Extensibility/Emitter.cs @@ -17,7 +17,8 @@ public interface IEmitterFactory { IAssemblyEmitter MakeAssemblyEmitter ( AssemblyTranslator assemblyTranslator, AssemblyDefinition assembly, - JavascriptFormatter formatter + JavascriptFormatter formatter, + IDictionary referenceOverrides ); IEnumerable GetAnalyzers (); diff --git a/JSIL/JavascriptAssemblyEmitter.cs b/JSIL/JavascriptAssemblyEmitter.cs index 02dad7cee..757a89c99 100644 --- a/JSIL/JavascriptAssemblyEmitter.cs +++ b/JSIL/JavascriptAssemblyEmitter.cs @@ -16,13 +16,16 @@ namespace JSIL { class JavascriptAssemblyEmitter : IAssemblyEmitter { public readonly AssemblyTranslator Translator; public readonly JavascriptFormatter Formatter; + private readonly IDictionary _referenceOverrides; public JavascriptAssemblyEmitter ( AssemblyTranslator assemblyTranslator, - JavascriptFormatter formatter + JavascriptFormatter formatter, + IDictionary referenceOverrides ) { Translator = assemblyTranslator; Formatter = formatter; + _referenceOverrides = referenceOverrides; } // HACK @@ -50,11 +53,29 @@ public void EmitHeader (bool stubbed) { Formatter.NewLine(); } + if (_referenceOverrides != null) + { + Formatter.LPar(); + Formatter.OpenFunction(string.Empty, null); + } + Formatter.DeclareAssembly(); Formatter.NewLine(); + + if (_referenceOverrides != null) { + Formatter.WriteReferencesOverrides(_referenceOverrides); + } } public void EmitFooter () { + if (_referenceOverrides != null) + { + Formatter.CloseBrace(); + Formatter.RPar(); + Formatter.LPar(); + Formatter.RPar(); + Formatter.Semicolon(); + } } public void EmitAssemblyEntryPoint (AssemblyDefinition assembly, MethodDefinition entryMethod, MethodSignature signature) { diff --git a/JSIL/JavascriptFormatter.cs b/JSIL/JavascriptFormatter.cs index a35fa6cf8..0ef764dda 100644 --- a/JSIL/JavascriptFormatter.cs +++ b/JSIL/JavascriptFormatter.cs @@ -181,6 +181,7 @@ public class JavascriptFormatter { protected readonly HashSet DeclaredNamespaces = new HashSet(); protected readonly bool Stubbed; + protected readonly string AssemblyDeclarationReplacement; protected uint _IndentLevel = 0; protected bool _IndentNeeded = false; @@ -196,6 +197,7 @@ public JavascriptFormatter ( TextWriter output, SourceMapBuilder sourceMapBuilder, ITypeInfoSource typeInfo, AssemblyManifest manifest, AssemblyDefinition assembly, Configuration configuration, + string assemblyDeclarationReplacement, bool stubbed ) { if (sourceMapBuilder != null) @@ -214,6 +216,7 @@ bool stubbed Assembly = assembly; Configuration = configuration; Stubbed = stubbed; + AssemblyDeclarationReplacement = assemblyDeclarationReplacement; PrivateToken = Manifest.GetPrivateToken(assembly); Manifest.AssignIdentifiers(); @@ -1164,10 +1167,30 @@ public void DeclareAssembly () { Space(); Identifier(PrivateToken.IDString); WriteRaw(" = "); - WriteRaw("JSIL.DeclareAssembly"); - LPar(); - Value(Assembly.FullName); - RPar(); + if (AssemblyDeclarationReplacement == null) + { + WriteRaw("JSIL.DeclareAssembly"); + LPar(); + Value(Assembly.FullName); + RPar(); + } + else + { + WriteRaw(AssemblyDeclarationReplacement); + } + Semicolon(); + } + } + + public void WriteReferencesOverrides(IDictionary overrides) + { + foreach (var reference in overrides) + { + WriteRaw("var"); + Space(); + Identifier(reference.Key.IDString); + WriteRaw(" = "); + WriteRaw(reference.Value); Semicolon(); } } diff --git a/JSIL/TypeInfoProvider.cs b/JSIL/TypeInfoProvider.cs index 1069e1663..497681109 100644 --- a/JSIL/TypeInfoProvider.cs +++ b/JSIL/TypeInfoProvider.cs @@ -341,6 +341,13 @@ public void AddProxyAssemblies (Action onProxiesFound, param } } + public ProxyInfo FindTypeProxy(TypeIdentifier identifier) + { + ProxyInfo proxy; + TypeProxies.TryGetValue(identifier, out proxy); + return proxy; + } + public ModuleInfo GetModuleInformation (ModuleDefinition module) { if (module == null) throw new ArgumentNullException("module"); diff --git a/JSIL/TypeInformation.cs b/JSIL/TypeInformation.cs index a203a710a..f04376965 100644 --- a/JSIL/TypeInformation.cs +++ b/JSIL/TypeInformation.cs @@ -532,6 +532,7 @@ public class TypeInfo { protected bool _IsExternal = false; protected bool _IsStubOnly = false; protected bool _IsUnstubbable = false; + protected bool _IsSuppressDeclaration = false; protected bool _MethodGroupsInitialized = false; protected List DeferredMethodSignatureSetUpdates = new List(); @@ -636,6 +637,7 @@ public TypeInfo (ITypeInfoSource source, ModuleInfo module, TypeDefinition type, _IsStubOnly = Metadata.HasAttribute("JSIL.Meta.JSStubOnly"); _IsUnstubbable = Metadata.HasAttribute("JSIL.Meta.JSNeverStub"); + _IsSuppressDeclaration = Metadata.HasAttribute("JSIL.Meta.JSSuppressTypeDeclaration"); if (_IsUnstubbable) { _IsStubOnly = false; @@ -988,6 +990,24 @@ public bool IsStubOnly } } + public bool IsSuppressDeclaration + { + get + { + if (_FullyInitialized) + return _IsSuppressDeclaration; + + /*if (Definition.DeclaringType != null) + { + var dt = Source.GetExisting(Definition.DeclaringType); + if ((dt != null) && dt.IsSuppressDeclaration) + return true; + }*/ + + return _IsSuppressDeclaration; + } + } + protected static bool ShouldNeverReplace (CustomAttribute ca) { return ca.AttributeType.FullName == "JSIL.Proxy.JSNeverReplace"; } diff --git a/Meta b/Meta index bf91263ef..25f4ab7a4 160000 --- a/Meta +++ b/Meta @@ -1 +1 @@ -Subproject commit bf91263efb4b508e5bc04f2ec10cffa95a5cd97e +Subproject commit 25f4ab7a40ade714dd4fa4c7949711ab438251c5 diff --git a/Proxies/BCL/JSIL.Bootstrap.Resources.cs b/Proxies/BCL/JSIL.Bootstrap.Resources.cs index 54f5dd97f..666116a62 100644 --- a/Proxies/BCL/JSIL.Bootstrap.Resources.cs +++ b/Proxies/BCL/JSIL.Bootstrap.Resources.cs @@ -21,6 +21,12 @@ public class System_Resources_ResourceSet [JSProxy(typeof(CultureInfo), JSProxyMemberPolicy.ReplaceDeclared, JSProxyAttributePolicy.ReplaceDeclared, JSProxyInterfacePolicy.ReplaceNone, false)] public class System_Globalization_CultureInfo { + [JSReplaceConstructor] + static System_Globalization_CultureInfo() + { + + } + [JSExternal] [JSReplaceConstructor] public System_Globalization_CultureInfo(string cultureId) @@ -112,5 +118,23 @@ public static CultureInfo CurrentCulture throw new NotImplementedException(); } } + + public bool IsReadOnly + { + [JSExternal] + get + { + throw new NotImplementedException(); + } + } + + public NumberFormatInfo NumberFormat + { + [JSExternal] + get + { + throw new NotImplementedException(); + } + } } } diff --git a/Proxies/BCL/System.cs b/Proxies/BCL/System.cs index 11b40ed5c..11d989625 100644 --- a/Proxies/BCL/System.cs +++ b/Proxies/BCL/System.cs @@ -1,7 +1,10 @@ namespace JSIL.Proxies.Bcl { using System.Collections.Generic; + using System.Globalization; + using System.Security; using System.Security.Cryptography.X509Certificates; + using System.Threading; using JSIL.Meta; using JSIL.Proxy; @@ -28,4 +31,22 @@ public class System_Security_Cryptography_X509Certificates_X509Certificate2 public class System_Security_Cryptography_X509Certificates_X509Utils { } + + [JSProxy(typeof(DateTimeFormatInfo), JSProxyMemberPolicy.ReplaceDeclared, JSProxyAttributePolicy.ReplaceDeclared, JSProxyInterfacePolicy.ReplaceNone, false)] + public class System_Globalization_DateTimeFormatInfo + { + [JSReplaceConstructor] + static System_Globalization_DateTimeFormatInfo() + { + } + } + + [JSProxy(typeof(SecurityContext), JSProxyMemberPolicy.ReplaceDeclared, JSProxyAttributePolicy.ReplaceDeclared, JSProxyInterfacePolicy.ReplaceNone, false)] + public class System_Security_SecurityContext + { + [JSReplaceConstructor] + static System_Security_SecurityContext() + { + } + } } diff --git a/Proxies/Numbers.cs b/Proxies/Numbers.cs index 32125ce70..f026d0140 100644 --- a/Proxies/Numbers.cs +++ b/Proxies/Numbers.cs @@ -18,12 +18,12 @@ public string ToString () { return base.ToString(); } - [JSReplacement("JSIL.NumberToFormattedString($this, null, $format)")] + [JSReplacement("$typeof(this).__PublicInterface__.$$ToString($this, $format, null)")] public string ToString (string format) { throw new InvalidOperationException(); } - [JSReplacement("JSIL.NumberToFormattedString($this, null, $format, $formatProvider)")] + [JSReplacement("$typeof(this).__PublicInterface__.$$ToString($this, $format, $formatProvider)")] public string ToString (string format, IFormatProvider formatProvider) { throw new InvalidOperationException(); } @@ -52,12 +52,12 @@ public string ToString () { throw new InvalidOperationException(); } - [JSReplacement("JSIL.NumberToFormattedString($this, null, $format)")] + [JSReplacement("$typeof(this).__PublicInterface__.$$ToString($this, $format, null)")] public string ToString (string format) { throw new InvalidOperationException(); } - [JSReplacement("JSIL.NumberToFormattedString($this, null, $format, $formatProvider)")] + [JSReplacement("$typeof(this).__PublicInterface__.$$ToString($this, $format, $formatProvider)")] public string ToString (string format, IFormatProvider formatProvider) { throw new InvalidOperationException(); } diff --git a/Proxies/Proxies.4.0.csproj b/Proxies/Proxies.4.0.csproj index 4af6cf9ec..741b4772a 100644 --- a/Proxies/Proxies.4.0.csproj +++ b/Proxies/Proxies.4.0.csproj @@ -40,6 +40,7 @@ + diff --git a/Proxies/SuppressDeclaration.cs b/Proxies/SuppressDeclaration.cs new file mode 100644 index 000000000..f24772108 --- /dev/null +++ b/Proxies/SuppressDeclaration.cs @@ -0,0 +1,47 @@ +namespace JSIL.Proxies +{ + using System; + using System.Globalization; + using System.Reflection; + using JSIL.Meta; + using JSIL.Proxy; + + [JSProxy( + new[] + { + typeof (object), typeof (ValueType), + typeof (Type), + typeof (MemberInfo), typeof (MethodBase), + typeof (MethodInfo), typeof (FieldInfo), + typeof (ConstructorInfo), typeof (PropertyInfo), typeof (EventInfo), + typeof (Array), typeof (Delegate), typeof (MulticastDelegate), + typeof (Byte), typeof (SByte), + typeof (UInt16), typeof (Int16), + typeof (UInt32), typeof (Int32), + typeof (UInt64), typeof (Int64), + typeof (Single), typeof (Double), + typeof (Boolean), typeof (Char), + typeof (Assembly), + typeof (Attribute), + typeof (Decimal), + typeof (IntPtr), typeof (UIntPtr), + typeof (NumberFormatInfo) + }, + inheritable: false)] + [JSSuppressTypeDeclaration] + public class SuppressDeclarationByType + { + } + + [JSProxy( + new[] + { + "System.Reflection.TypeInfo", "System.RuntimeType", + "System.Reflection.RuntimeAssembly" + }, + inheritable: false)] + [JSSuppressTypeDeclaration] + public class SuppressDeclarationByString + { + } +} diff --git a/Tests.DCE/Tests.DCE.csproj b/Tests.DCE/Tests.DCE.csproj index ea96f96ae..3b7acefad 100644 --- a/Tests.DCE/Tests.DCE.csproj +++ b/Tests.DCE/Tests.DCE.csproj @@ -46,19 +46,6 @@ prompt false - - true - false - - - false - - - false - - - false - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll diff --git a/Tests/SimpleTestCases/IntegerToStringFormatted.cs b/Tests/SimpleTestCases/FailsOnMono/IntegerToStringFormatted.cs similarity index 100% rename from Tests/SimpleTestCases/IntegerToStringFormatted.cs rename to Tests/SimpleTestCases/FailsOnMono/IntegerToStringFormatted.cs diff --git a/Tests/SimpleTestCases/UInt64_Issue855.cs b/Tests/SimpleTestCases/UInt64_Issue855.cs new file mode 100644 index 000000000..a8c770638 --- /dev/null +++ b/Tests/SimpleTestCases/UInt64_Issue855.cs @@ -0,0 +1,10 @@ +using System; + +public static class Program +{ + public static void Main(string[] args) + { + ulong l = 0x80000000; + Console.WriteLine(l); + } +} \ No newline at end of file diff --git a/Tests/SimpleTests.csproj b/Tests/SimpleTests.csproj index 29abbb8af..cb198c400 100644 --- a/Tests/SimpleTests.csproj +++ b/Tests/SimpleTests.csproj @@ -126,6 +126,7 @@ + @@ -262,7 +263,7 @@ - +