aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js8
-rw-r--r--src/compiler.js28
-rw-r--r--src/jsifier.js118
-rw-r--r--src/library.js6
-rw-r--r--src/long.js2804
-rw-r--r--src/modules.js63
-rw-r--r--src/parseTools.js10
-rw-r--r--src/preamble.js4
-rw-r--r--src/settings.js2
9 files changed, 1555 insertions, 1488 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 1849b58d..a6a37400 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -1346,6 +1346,14 @@ function analyzer(data, sidePass) {
}
});
});
+
+ if (func.ident in NECESSARY_BLOCKADDRS) {
+ Functions.blockAddresses[func.ident] = {};
+ for (var needed in NECESSARY_BLOCKADDRS[func.ident]) {
+ assert(needed in func.labelIds);
+ Functions.blockAddresses[func.ident][needed] = func.labelIds[needed];
+ }
+ }
});
this.forwardItem(item, 'StackAnalyzer');
}
diff --git a/src/compiler.js b/src/compiler.js
index e589646b..3220c977 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -129,7 +129,13 @@ load('settings.js');
var settings_file = arguments_[0];
var ll_file = arguments_[1];
-additionalLibraries = Array.prototype.slice.call(arguments_, 2);
+phase = arguments_[2];
+if (phase == 'pre') {
+ additionalLibraries = Array.prototype.slice.call(arguments_, 3);
+} else {
+ var forwardedDataFile = arguments_[3];
+ additionalLibraries = Array.prototype.slice.call(arguments_, 4);
+}
if (settings_file) {
var settings = JSON.parse(read(settings_file));
@@ -191,6 +197,15 @@ load('jsifier.js');
globalEval(processMacros(preprocess(read('runtime.js'))));
Runtime.QUANTUM_SIZE = QUANTUM_SIZE;
+var temp = {};
+for (var i = 0; i < NECESSARY_BLOCKADDRS.length; i++) {
+ var func = toNiceIdent(NECESSARY_BLOCKADDRS[i][0]);
+ var label = toNiceIdent(NECESSARY_BLOCKADDRS[i][1]);
+ if (!temp[func]) temp[func] = {};
+ temp[func][label] = 1;
+}
+NECESSARY_BLOCKADDRS = temp;
+
//===============================
// Main
//===============================
@@ -209,8 +224,17 @@ raw = null;
// Pre-process the LLVM assembly
+//printErr('JS compiler in action, phase ' + phase);
+
Debugging.handleMetadata(lines);
-PreProcessor.eliminateUnneededIntrinsics(lines);
+
+if (phase != 'pre') {
+ PassManager.load(read(forwardedDataFile));
+
+ if (phase == 'funcs') {
+ PreProcessor.eliminateUnneededIntrinsics(lines);
+ }
+}
// Do it
diff --git a/src/jsifier.js b/src/jsifier.js
index 78f48118..21628079 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -13,33 +13,36 @@ function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
if (mainPass) {
- // We will start to print out the data, but must do so carefully - we are
- // dealing with potentially *huge* strings. Convenient replacements and
- // manipulations may create in-memory copies, and we may OOM.
- //
- // Final shape that will be created:
- // shell
- // (body)
- // preamble
- // runtime
- // generated code
- // postamble
- // global_vars
- //
- // First, we print out everything until the generated code. Then the
- // functions will print themselves out as they are parsed. Finally, we
- // will call finalCombiner in the main pass, to print out everything
- // else. This lets us not hold any strings in memory, we simply print
- // things out as they are ready.
-
var shellFile = SHELL_FILE ? SHELL_FILE : (BUILD_AS_SHARED_LIB ? 'shell_sharedlib.js' : 'shell.js');
- var shellParts = read(shellFile).split('{{BODY}}');
- print(shellParts[0]);
- var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js';
- var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime())));
- print(pre);
- Functions.implementedFunctions = set(data.unparsedFunctions.map(function(func) { return func.ident }));
+ if (phase == 'pre') {
+ // We will start to print out the data, but must do so carefully - we are
+ // dealing with potentially *huge* strings. Convenient replacements and
+ // manipulations may create in-memory copies, and we may OOM.
+ //
+ // Final shape that will be created:
+ // shell
+ // (body)
+ // preamble
+ // runtime
+ // generated code
+ // postamble
+ // global_vars
+ //
+ // First, we print out everything until the generated code. Then the
+ // functions will print themselves out as they are parsed. Finally, we
+ // will call finalCombiner in the main pass, to print out everything
+ // else. This lets us not hold any strings in memory, we simply print
+ // things out as they are ready.
+
+ var shellParts = read(shellFile).split('{{BODY}}');
+ print(shellParts[0]);
+ var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js';
+ var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime())));
+ print(pre);
+
+ Functions.implementedFunctions = set(data.unparsedFunctions.map(function(func) { return func.ident }));
+ }
}
// Does simple 'macro' substitution, using Django-like syntax,
@@ -83,19 +86,8 @@ function JSify(data, functionsOnly, givenFunctions) {
// Functions
- Functions.currFunctions = !mainPass ? givenFunctions.currFunctions : {};
Functions.currExternalFunctions = !mainPass ? givenFunctions.currExternalFunctions : {};
- // Now that first-pass analysis has completed (so we have basic types, etc.), we can get around to handling unparsedFunctions
- (!mainPass ? data.functions : data.unparsedFunctions.concat(data.functions)).forEach(function(func) {
- // Save just what we need, to save memory
- Functions.currFunctions[func.ident] = {
- hasVarArgs: func.hasVarArgs,
- numParams: func.params.length,
- labelIds: func.labelIds // TODO: We need this for globals, but perhaps we can calculate them early and free this
- };
- });
-
data.functionStubs.forEach(function(func) {
// Don't overwrite stubs that have more info.
if (!Functions.currExternalFunctions.hasOwnProperty(func.ident) ||
@@ -107,24 +99,26 @@ function JSify(data, functionsOnly, givenFunctions) {
}
});
- var MAX_BATCH_FUNC_LINES = 1000;
- while (data.unparsedFunctions.length > 0) {
- var currFuncLines = [];
- var currBaseLineNums = [];
- while (currFuncLines.length == 0 ||
- (data.unparsedFunctions.length > 0 && currFuncLines.length + data.unparsedFunctions[0].lines.length <= MAX_BATCH_FUNC_LINES)) {
- currBaseLineNums.push([currFuncLines.length, data.unparsedFunctions[0].lineNum-1]);
- currFuncLines = currFuncLines.concat(data.unparsedFunctions[0].lines); // for first one, assign, do not concat?
- data.unparsedFunctions.shift();
+ if (phase == 'funcs') { // pre has function shells, just to defined implementedFunctions
+ var MAX_BATCH_FUNC_LINES = 1000;
+ while (data.unparsedFunctions.length > 0) {
+ var currFuncLines = [];
+ var currBaseLineNums = [];
+ while (currFuncLines.length == 0 ||
+ (data.unparsedFunctions.length > 0 && currFuncLines.length + data.unparsedFunctions[0].lines.length <= MAX_BATCH_FUNC_LINES)) {
+ currBaseLineNums.push([currFuncLines.length, data.unparsedFunctions[0].lineNum-1]);
+ currFuncLines = currFuncLines.concat(data.unparsedFunctions[0].lines); // for first one, assign, do not concat?
+ data.unparsedFunctions.shift();
+ }
+ dprint('unparsedFunctions','====================\n// Processing function batch of ' + currBaseLineNums.length +
+ ' functions, ' + currFuncLines.length + ' lines, functions left: ' + data.unparsedFunctions.length);
+ if (DEBUG_MEMORY) MemoryDebugger.tick('pre-func');
+ JSify(analyzer(intertyper(currFuncLines, true, currBaseLineNums), true), true, Functions);
+ if (DEBUG_MEMORY) MemoryDebugger.tick('post-func');
}
- dprint('unparsedFunctions','====================\n// Processing function batch of ' + currBaseLineNums.length +
- ' functions, ' + currFuncLines.length + ' lines, functions left: ' + data.unparsedFunctions.length);
- if (DEBUG_MEMORY) MemoryDebugger.tick('pre-func');
- JSify(analyzer(intertyper(currFuncLines, true, currBaseLineNums), true), true, Functions);
- if (DEBUG_MEMORY) MemoryDebugger.tick('post-func');
+ currFuncLines = currBaseLineNums = null; // Do not hold on to anything from inside that loop (JS function scoping..)
+ data.unparsedFunctions = null;
}
- currFuncLines = currBaseLineNums = null; // Do not hold on to anything from inside that loop (JS function scoping..)
- data.unparsedFunctions = null;
// Actors
@@ -1221,19 +1215,20 @@ function JSify(data, functionsOnly, givenFunctions) {
if (!mainPass) {
var generated = itemsDict.function.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.GlobalVariable).concat(itemsDict.GlobalVariablePostSet);
- Functions.allIdents = Functions.allIdents.concat(itemsDict.function.map(function(func) {
- return func.ident;
- }).filter(function(func) {
- return IGNORED_FUNCTIONS.indexOf(func.ident) < 0;
- }));
if (!DEBUG_MEMORY) print(generated.map(function(item) { return item.JS }).join('\n'));
return;
}
- // This is the main pass. Print out the generated code that we have here, together with the
+ if (phase == 'pre' || phase == 'funcs') {
+ // serialize out the data that later passes need
+ PassManager.serialize(); // XXX for funcs pass, do not serialize it all. I think we just need which were indexized.
+ return;
+ }
+
+ // This is the main 'post' pass. Print out the generated code that we have here, together with the
// rest of the output that we started to print out earlier (see comment on the
// "Final shape that will be created").
- if (PRECISE_I64_MATH && preciseI64MathUsed) {
+ if (PRECISE_I64_MATH && Types.preciseI64MathUsed) {
print(read('long.js'));
} else {
print('// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included');
@@ -1264,9 +1259,12 @@ function JSify(data, functionsOnly, givenFunctions) {
print(postParts[1]);
+ var shellParts = read(shellFile).split('{{BODY}}');
print(shellParts[1]);
// Print out some useful metadata (for additional optimizations later, like the eliminator)
- print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + JSON.stringify(Functions.allIdents) + '\n');
+ print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + JSON.stringify(keys(Functions.implementedFunctions).filter(function(func) {
+ return IGNORED_FUNCTIONS.indexOf(func.ident) < 0;
+ })) + '\n');
return null;
}
diff --git a/src/library.js b/src/library.js
index 25195415..73109334 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4748,7 +4748,7 @@ LibraryManager.library = {
},
__assert_func: function(filename, line, func, condition) {
- throw 'Assertion failed: ' + Pointer_stringify(condition) + ', at: ' + [Pointer_stringify(filename), line, Pointer_stringify(func)];
+ throw 'Assertion failed: ' + (condition ? Pointer_stringify(condition) : 'unknown condition') + ', at: ' + [filename ? Pointer_stringify(filename) : 'unknown filename', line, func ? Pointer_stringify(func) : 'unknown function'];
},
__cxa_guard_acquire: function(variable) {
@@ -5042,7 +5042,7 @@ LibraryManager.library = {
};
},
- llvm_uadd_with_overflow_i64__deps: [function() { preciseI64MathUsed = 1 }],
+ llvm_uadd_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }],
llvm_uadd_with_overflow_i64: function(xl, xh, yl, yh) {
i64Math.add(xl, xh, yl, yh);
return {
@@ -5051,7 +5051,7 @@ LibraryManager.library = {
};
},
- llvm_umul_with_overflow_i64__deps: [function() { preciseI64MathUsed = 1 }],
+ llvm_umul_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }],
llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) {
i64Math.mul(xl, xh, yl, yh);
return {
diff --git a/src/long.js b/src/long.js
index 71cffa79..d5770e48 100644
--- a/src/long.js
+++ b/src/long.js
@@ -24,1609 +24,1609 @@
*/
var i64Math = (function() { // Emscripten wrapper
-var goog = { math: {} };
+ var goog = { math: {} };
-/**
- * Constructs a 64-bit two's-complement integer, given its low and high 32-bit
- * values as *signed* integers. See the from* functions below for more
- * convenient ways of constructing Longs.
- *
- * The internal representation of a long is the two given signed, 32-bit values.
- * We use 32-bit pieces because these are the size of integers on which
- * Javascript performs bit-operations. For operations like addition and
- * multiplication, we split each number into 16-bit pieces, which can easily be
- * multiplied within Javascript's floating-point representation without overflow
- * or change in sign.
- *
- * In the algorithms below, we frequently reduce the negative case to the
- * positive case by negating the input(s) and then post-processing the result.
- * Note that we must ALWAYS check specially whether those values are MIN_VALUE
- * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
- * a positive number, it overflows back into a negative). Not handling this
- * case would often result in infinite recursion.
- *
- * @param {number} low The low (signed) 32 bits of the long.
- * @param {number} high The high (signed) 32 bits of the long.
- * @constructor
- */
-goog.math.Long = function(low, high) {
/**
- * @type {number}
- * @private
+ * Constructs a 64-bit two's-complement integer, given its low and high 32-bit
+ * values as *signed* integers. See the from* functions below for more
+ * convenient ways of constructing Longs.
+ *
+ * The internal representation of a long is the two given signed, 32-bit values.
+ * We use 32-bit pieces because these are the size of integers on which
+ * Javascript performs bit-operations. For operations like addition and
+ * multiplication, we split each number into 16-bit pieces, which can easily be
+ * multiplied within Javascript's floating-point representation without overflow
+ * or change in sign.
+ *
+ * In the algorithms below, we frequently reduce the negative case to the
+ * positive case by negating the input(s) and then post-processing the result.
+ * Note that we must ALWAYS check specially whether those values are MIN_VALUE
+ * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
+ * a positive number, it overflows back into a negative). Not handling this
+ * case would often result in infinite recursion.
+ *
+ * @param {number} low The low (signed) 32 bits of the long.
+ * @param {number} high The high (signed) 32 bits of the long.
+ * @constructor
*/
- this.low_ = low | 0; // force into 32 signed bits.
+ goog.math.Long = function(low, high) {
+ /**
+ * @type {number}
+ * @private
+ */
+ this.low_ = low | 0; // force into 32 signed bits.
- /**
- * @type {number}
- * @private
- */
- this.high_ = high | 0; // force into 32 signed bits.
-};
+ /**
+ * @type {number}
+ * @private
+ */
+ this.high_ = high | 0; // force into 32 signed bits.
+ };
-// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
-// from* methods on which they depend.
+ // NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
+ // from* methods on which they depend.
-/**
- * A cache of the Long representations of small integer values.
- * @type {!Object}
- * @private
- */
-goog.math.Long.IntCache_ = {};
+ /**
+ * A cache of the Long representations of small integer values.
+ * @type {!Object}
+ * @private
+ */
+ goog.math.Long.IntCache_ = {};
-/**
- * Returns a Long representing the given (32-bit) integer value.
- * @param {number} value The 32-bit integer in question.
- * @return {!goog.math.Long} The corresponding Long value.
- */
-goog.math.Long.fromInt = function(value) {
- if (-128 <= value && value < 128) {
- var cachedObj = goog.math.Long.IntCache_[value];
- if (cachedObj) {
- return cachedObj;
+ /**
+ * Returns a Long representing the given (32-bit) integer value.
+ * @param {number} value The 32-bit integer in question.
+ * @return {!goog.math.Long} The corresponding Long value.
+ */
+ goog.math.Long.fromInt = function(value) {
+ if (-128 <= value && value < 128) {
+ var cachedObj = goog.math.Long.IntCache_[value];
+ if (cachedObj) {
+ return cachedObj;
+ }
}
- }
- var obj = new goog.math.Long(value | 0, value < 0 ? -1 : 0);
- if (-128 <= value && value < 128) {
- goog.math.Long.IntCache_[value] = obj;
- }
- return obj;
-};
+ var obj = new goog.math.Long(value | 0, value < 0 ? -1 : 0);
+ if (-128 <= value && value < 128) {
+ goog.math.Long.IntCache_[value] = obj;
+ }
+ return obj;
+ };
-/**
- * Returns a Long representing the given value, provided that it is a finite
- * number. Otherwise, zero is returned.
- * @param {number} value The number in question.
- * @return {!goog.math.Long} The corresponding Long value.
- */
-goog.math.Long.fromNumber = function(value) {
- if (isNaN(value) || !isFinite(value)) {
- return goog.math.Long.ZERO;
- } else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) {
- return goog.math.Long.MIN_VALUE;
- } else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) {
- return goog.math.Long.MAX_VALUE;
- } else if (value < 0) {
- return goog.math.Long.fromNumber(-value).negate();
- } else {
- return new goog.math.Long(
- (value % goog.math.Long.TWO_PWR_32_DBL_) | 0,
- (value / goog.math.Long.TWO_PWR_32_DBL_) | 0);
- }
-};
+ /**
+ * Returns a Long representing the given value, provided that it is a finite
+ * number. Otherwise, zero is returned.
+ * @param {number} value The number in question.
+ * @return {!goog.math.Long} The corresponding Long value.
+ */
+ goog.math.Long.fromNumber = function(value) {
+ if (isNaN(value) || !isFinite(value)) {
+ return goog.math.Long.ZERO;
+ } else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) {
+ return goog.math.Long.MIN_VALUE;
+ } else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) {
+ return goog.math.Long.MAX_VALUE;
+ } else if (value < 0) {
+ return goog.math.Long.fromNumber(-value).negate();
+ } else {
+ return new goog.math.Long(
+ (value % goog.math.Long.TWO_PWR_32_DBL_) | 0,
+ (value / goog.math.Long.TWO_PWR_32_DBL_) | 0);
+ }
+ };
-/**
- * Returns a Long representing the 64-bit integer that comes by concatenating
- * the given high and low bits. Each is assumed to use 32 bits.
- * @param {number} lowBits The low 32-bits.
- * @param {number} highBits The high 32-bits.
- * @return {!goog.math.Long} The corresponding Long value.
- */
-goog.math.Long.fromBits = function(lowBits, highBits) {
- return new goog.math.Long(lowBits, highBits);
-};
+ /**
+ * Returns a Long representing the 64-bit integer that comes by concatenating
+ * the given high and low bits. Each is assumed to use 32 bits.
+ * @param {number} lowBits The low 32-bits.
+ * @param {number} highBits The high 32-bits.
+ * @return {!goog.math.Long} The corresponding Long value.
+ */
+ goog.math.Long.fromBits = function(lowBits, highBits) {
+ return new goog.math.Long(lowBits, highBits);
+ };
-/**
- * Returns a Long representation of the given string, written using the given
- * radix.
- * @param {string} str The textual representation of the Long.
- * @param {number=} opt_radix The radix in which the text is written.
- * @return {!goog.math.Long} The corresponding Long value.
- */
-goog.math.Long.fromString = function(str, opt_radix) {
- if (str.length == 0) {
- throw Error('number format error: empty string');
- }
+ /**
+ * Returns a Long representation of the given string, written using the given
+ * radix.
+ * @param {string} str The textual representation of the Long.
+ * @param {number=} opt_radix The radix in which the text is written.
+ * @return {!goog.math.Long} The corresponding Long value.
+ */
+ goog.math.Long.fromString = function(str, opt_radix) {
+ if (str.length == 0) {
+ throw Error('number format error: empty string');
+ }
- var radix = opt_radix || 10;
- if (radix < 2 || 36 < radix) {
- throw Error('radix out of range: ' + radix);
- }
+ var radix = opt_radix || 10;
+ if (radix < 2 || 36 < radix) {
+ throw Error('radix out of range: ' + radix);
+ }
- if (str.charAt(0) == '-') {
- return goog.math.Long.fromString(str.substring(1), radix).negate();
- } else if (str.indexOf('-') >= 0) {
- throw Error('number format error: interior "-" character: ' + str);
- }
+ if (str.charAt(0) == '-') {
+ return goog.math.Long.fromString(str.substring(1), radix).negate();
+ } else if (str.indexOf('-') >= 0) {
+ throw Error('number format error: interior "-" character: ' + str);
+ }
- // Do several (8) digits each time through the loop, so as to
- // minimize the calls to the very expensive emulated div.
- var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8));
-
- var result = goog.math.Long.ZERO;
- for (var i = 0; i < str.length; i += 8) {
- var size = Math.min(8, str.length - i);
- var value = parseInt(str.substring(i, i + size), radix);
- if (size < 8) {
- var power = goog.math.Long.fromNumber(Math.pow(radix, size));
- result = result.multiply(power).add(goog.math.Long.fromNumber(value));
- } else {
- result = result.multiply(radixToPower);
- result = result.add(goog.math.Long.fromNumber(value));
+ // Do several (8) digits each time through the loop, so as to
+ // minimize the calls to the very expensive emulated div.
+ var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8));
+
+ var result = goog.math.Long.ZERO;
+ for (var i = 0; i < str.length; i += 8) {
+ var size = Math.min(8, str.length - i);
+ var value = parseInt(str.substring(i, i + size), radix);
+ if (size < 8) {
+ var power = goog.math.Long.fromNumber(Math.pow(radix, size));
+ result = result.multiply(power).add(goog.math.Long.fromNumber(value));
+ } else {
+ result = result.multiply(radixToPower);
+ result = result.add(goog.math.Long.fromNumber(value));
+ }
}
- }
- return result;
-};
+ return result;
+ };
-// NOTE: the compiler should inline these constant values below and then remove
-// these variables, so there should be no runtime penalty for these.
+ // NOTE: the compiler should inline these constant values below and then remove
+ // these variables, so there should be no runtime penalty for these.
-/**
- * Number used repeated below in calculations. This must appear before the
- * first call to any from* function below.
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16;
+ /**
+ * Number used repeated below in calculations. This must appear before the
+ * first call to any from* function below.
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_24_DBL_ = 1 << 24;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_24_DBL_ = 1 << 24;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_32_DBL_ =
- goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_32_DBL_ =
+ goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_31_DBL_ =
- goog.math.Long.TWO_PWR_32_DBL_ / 2;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_31_DBL_ =
+ goog.math.Long.TWO_PWR_32_DBL_ / 2;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_48_DBL_ =
- goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_48_DBL_ =
+ goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_64_DBL_ =
- goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_64_DBL_ =
+ goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_;
-/**
- * @type {number}
- * @private
- */
-goog.math.Long.TWO_PWR_63_DBL_ =
- goog.math.Long.TWO_PWR_64_DBL_ / 2;
+ /**
+ * @type {number}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_63_DBL_ =
+ goog.math.Long.TWO_PWR_64_DBL_ / 2;
-/** @type {!goog.math.Long} */
-goog.math.Long.ZERO = goog.math.Long.fromInt(0);
+ /** @type {!goog.math.Long} */
+ goog.math.Long.ZERO = goog.math.Long.fromInt(0);
-/** @type {!goog.math.Long} */
-goog.math.Long.ONE = goog.math.Long.fromInt(1);
+ /** @type {!goog.math.Long} */
+ goog.math.Long.ONE = goog.math.Long.fromInt(1);
-/** @type {!goog.math.Long} */
-goog.math.Long.NEG_ONE = goog.math.Long.fromInt(-1);
+ /** @type {!goog.math.Long} */
+ goog.math.Long.NEG_ONE = goog.math.Long.fromInt(-1);
-/** @type {!goog.math.Long} */
-goog.math.Long.MAX_VALUE =
- goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
+ /** @type {!goog.math.Long} */
+ goog.math.Long.MAX_VALUE =
+ goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
-/** @type {!goog.math.Long} */
-goog.math.Long.MIN_VALUE = goog.math.Long.fromBits(0, 0x80000000 | 0);
+ /** @type {!goog.math.Long} */
+ goog.math.Long.MIN_VALUE = goog.math.Long.fromBits(0, 0x80000000 | 0);
-/**
- * @type {!goog.math.Long}
- * @private
- */
-goog.math.Long.TWO_PWR_24_ = goog.math.Long.fromInt(1 << 24);
+ /**
+ * @type {!goog.math.Long}
+ * @private
+ */
+ goog.math.Long.TWO_PWR_24_ = goog.math.Long.fromInt(1 << 24);
-/** @return {number} The value, assuming it is a 32-bit integer. */
-goog.math.Long.prototype.toInt = function() {
- return this.low_;
-};
+ /** @return {number} The value, assuming it is a 32-bit integer. */
+ goog.math.Long.prototype.toInt = function() {
+ return this.low_;
+ };
-/** @return {number} The closest floating-point representation to this value. */
-goog.math.Long.prototype.toNumber = function() {
- return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ +
- this.getLowBitsUnsigned();
-};
+ /** @return {number} The closest floating-point representation to this value. */
+ goog.math.Long.prototype.toNumber = function() {
+ return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ +
+ this.getLowBitsUnsigned();
+ };
-/**
- * @param {number=} opt_radix The radix in which the text should be written.
- * @return {string} The textual representation of this value.
- */
-goog.math.Long.prototype.toString = function(opt_radix) {
- var radix = opt_radix || 10;
- if (radix < 2 || 36 < radix) {
- throw Error('radix out of range: ' + radix);
- }
+ /**
+ * @param {number=} opt_radix The radix in which the text should be written.
+ * @return {string} The textual representation of this value.
+ */
+ goog.math.Long.prototype.toString = function(opt_radix) {
+ var radix = opt_radix || 10;
+ if (radix < 2 || 36 < radix) {
+ throw Error('radix out of range: ' + radix);
+ }
- if (this.isZero()) {
- return '0';
- }
+ if (this.isZero()) {
+ return '0';
+ }
- if (this.isNegative()) {
- if (this.equals(goog.math.Long.MIN_VALUE)) {
- // We need to change the Long value before it can be negated, so we remove
- // the bottom-most digit in this base and then recurse to do the rest.
- var radixLong = goog.math.Long.fromNumber(radix);
- var div = this.div(radixLong);
- var rem = div.multiply(radixLong).subtract(this);
- return div.toString(radix) + rem.toInt().toString(radix);
- } else {
- return '-' + this.negate().toString(radix);
+ if (this.isNegative()) {
+ if (this.equals(goog.math.Long.MIN_VALUE)) {
+ // We need to change the Long value before it can be negated, so we remove
+ // the bottom-most digit in this base and then recurse to do the rest.
+ var radixLong = goog.math.Long.fromNumber(radix);
+ var div = this.div(radixLong);
+ var rem = div.multiply(radixLong).subtract(this);
+ return div.toString(radix) + rem.toInt().toString(radix);
+ } else {
+ return '-' + this.negate().toString(radix);
+ }
}
- }
- // Do several (6) digits each time through the loop, so as to
- // minimize the calls to the very expensive emulated div.
- var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6));
+ // Do several (6) digits each time through the loop, so as to
+ // minimize the calls to the very expensive emulated div.
+ var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6));
- var rem = this;
- var result = '';
- while (true) {
- var remDiv = rem.div(radixToPower);
- var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt();
- var digits = intval.toString(radix);
+ var rem = this;
+ var result = '';
+ while (true) {
+ var remDiv = rem.div(radixToPower);
+ var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt();
+ var digits = intval.toString(radix);
- rem = remDiv;
- if (rem.isZero()) {
- return digits + result;
- } else {
- while (digits.length < 6) {
- digits = '0' + digits;
+ rem = remDiv;
+ if (rem.isZero()) {
+ return digits + result;
+ } else {
+ while (digits.length < 6) {
+ digits = '0' + digits;
+ }
+ result = '' + digits + result;
}
- result = '' + digits + result;
}
- }
-};
+ };
-/** @return {number} The high 32-bits as a signed value. */
-goog.math.Long.prototype.getHighBits = function() {
- return this.high_;
-};
+ /** @return {number} The high 32-bits as a signed value. */
+ goog.math.Long.prototype.getHighBits = function() {
+ return this.high_;
+ };
-/** @return {number} The low 32-bits as a signed value. */
-goog.math.Long.prototype.getLowBits = function() {
- return this.low_;
-};
+ /** @return {number} The low 32-bits as a signed value. */
+ goog.math.Long.prototype.getLowBits = function() {
+ return this.low_;
+ };
-/** @return {number} The low 32-bits as an unsigned value. */
-goog.math.Long.prototype.getLowBitsUnsigned = function() {
- return (this.low_ >= 0) ?
- this.low_ : goog.math.Long.TWO_PWR_32_DBL_ + this.low_;
-};
+ /** @return {number} The low 32-bits as an unsigned value. */
+ goog.math.Long.prototype.getLowBitsUnsigned = function() {
+ return (this.low_ >= 0) ?
+ this.low_ : goog.math.Long.TWO_PWR_32_DBL_ + this.low_;
+ };
-/**
- * @return {number} Returns the number of bits needed to represent the absolute
- * value of this Long.
- */
-goog.math.Long.prototype.getNumBitsAbs = function() {
- if (this.isNegative()) {
- if (this.equals(goog.math.Long.MIN_VALUE)) {
- return 64;
+ /**
+ * @return {number} Returns the number of bits needed to represent the absolute
+ * value of this Long.
+ */
+ goog.math.Long.prototype.getNumBitsAbs = function() {
+ if (this.isNegative()) {
+ if (this.equals(goog.math.Long.MIN_VALUE)) {
+ return 64;
+ } else {
+ return this.negate().getNumBitsAbs();
+ }
} else {
- return this.negate().getNumBitsAbs();
- }
- } else {
- var val = this.high_ != 0 ? this.high_ : this.low_;
- for (var bit = 31; bit > 0; bit--) {
- if ((val & (1 << bit)) != 0) {
- break;
+ var val = this.high_ != 0 ? this.high_ : this.low_;
+ for (var bit = 31; bit > 0; bit--) {
+ if ((val & (1 << bit)) != 0) {
+ break;
+ }
}
+ return this.high_ != 0 ? bit + 33 : bit + 1;
}
- return this.high_ != 0 ? bit + 33 : bit + 1;
- }
-};
+ };
-/** @return {boolean} Whether this value is zero. */
-goog.math.Long.prototype.isZero = function() {
- return this.high_ == 0 && this.low_ == 0;
-};
+ /** @return {boolean} Whether this value is zero. */
+ goog.math.Long.prototype.isZero = function() {
+ return this.high_ == 0 && this.low_ == 0;
+ };
-/** @return {boolean} Whether this value is negative. */
-goog.math.Long.prototype.isNegative = function() {
- return this.high_ < 0;
-};
+ /** @return {boolean} Whether this value is negative. */
+ goog.math.Long.prototype.isNegative = function() {
+ return this.high_ < 0;
+ };
-/** @return {boolean} Whether this value is odd. */
-goog.math.Long.prototype.isOdd = function() {
- return (this.low_ & 1) == 1;
-};
+ /** @return {boolean} Whether this value is odd. */
+ goog.math.Long.prototype.isOdd = function() {
+ return (this.low_ & 1) == 1;
+ };
-/**
- * @param {goog.math.Long} other Long to compare against.
- * @return {boolean} Whether this Long equals the other.
- */
-goog.math.Long.prototype.equals = function(other) {
- return (this.high_ == other.high_) && (this.low_ == other.low_);
-};
+ /**
+ * @param {goog.math.Long} other Long to compare against.
+ * @return {boolean} Whether this Long equals the other.
+ */
+ goog.math.Long.prototype.equals = function(other) {
+ return (this.high_ == other.high_) && (this.low_ == other.low_);
+ };
-/**
- * @param {goog.math.Long} other Long to compare against.
- * @return {boolean} Whether this Long does not equal the other.
- */
-goog.math.Long.prototype.notEquals = function(other) {
- return (this.high_ != other.high_) || (this.low_ != other.low_);
-};
+ /**
+ * @param {goog.math.Long} other Long to compare against.
+ * @return {boolean} Whether this Long does not equal the other.
+ */
+ goog.math.Long.prototype.notEquals = function(other) {
+ return (this.high_ !