Spaces:
Running
Running
| /* Smalltalk from Squeak4.5 with VMMaker 4.13.6 translated as JS source on 3 November 2014 1:52:21 pm */ | |
| /* Automatically generated by | |
| JSSmartSyntaxPluginCodeGenerator VMMakerJS-bf.15 uuid: fd4e10f2-3773-4e80-8bb5-c4b471a014e5 | |
| from | |
| LargeIntegersPlugin VMMaker-bf.353 uuid: 8ae25e7e-8d2c-451e-8277-598b30e9c002 | |
| */ | |
| (function LargeIntegers() { | |
| ; | |
| var VM_PROXY_MAJOR = 1; | |
| var VM_PROXY_MINOR = 11; | |
| /*** Functions ***/ | |
| function CLASSOF(obj) { return typeof obj === "number" ? interpreterProxy.classSmallInteger() : obj.sqClass } | |
| function SIZEOF(obj) { return obj.pointers ? obj.pointers.length : obj.words ? obj.words.length : obj.bytes ? obj.bytes.length : 0 } | |
| function BYTESIZEOF(obj) { return obj.bytes ? obj.bytes.length : obj.words ? obj.words.length * 4 : 0 } | |
| function DIV(a, b) { return Math.floor(a / b) | 0; } // integer division | |
| function MOD(a, b) { return a - DIV(a, b) * b | 0; } // signed modulus | |
| function SHL(a, b) { return b > 31 ? 0 : a << b; } // fix JS shift | |
| function SHR(a, b) { return b > 31 ? 0 : a >>> b; } // fix JS shift | |
| function SHIFT(a, b) { return b < 0 ? (b < -31 ? 0 : a >>> (0-b) ) : (b > 31 ? 0 : a << b); } | |
| /*** Variables ***/ | |
| var andOpIndex = 0; | |
| var interpreterProxy = null; | |
| var moduleName = "LargeIntegers v1.5 (e)"; | |
| var orOpIndex = 1; | |
| var xorOpIndex = 2; | |
| /* Argument has to be aBytesOop! */ | |
| /* Tests for any magnitude bits in the interval from start to stopArg. */ | |
| function anyBitOfBytesfromto(aBytesOop, start, stopArg) { | |
| var lastByteIx; | |
| var digit; | |
| var magnitude; | |
| var leftShift; | |
| var rightShift; | |
| var firstByteIx; | |
| var stop; | |
| var mask; | |
| var ix; | |
| // missing DebugCode; | |
| if ((start < 1) || (stopArg < 1)) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| magnitude = aBytesOop; | |
| stop = Math.min(stopArg, highBitOfBytes(magnitude)); | |
| if (start > stop) { | |
| return false; | |
| } | |
| firstByteIx = ((start - 1) >> 3) + 1; | |
| lastByteIx = ((stop - 1) >> 3) + 1; | |
| rightShift = MOD((start - 1), 8); | |
| leftShift = 7 - (MOD((stop - 1), 8)); | |
| if (firstByteIx === lastByteIx) { | |
| mask = (SHL(255, rightShift)) & (SHR(255, leftShift)); | |
| digit = digitOfBytesat(magnitude, firstByteIx); | |
| return (digit & mask) !== 0; | |
| } | |
| if ((SHR(digitOfBytesat(magnitude, firstByteIx), rightShift)) !== 0) { | |
| return true; | |
| } | |
| for (ix = (firstByteIx + 1); ix <= (lastByteIx - 1); ix++) { | |
| if (digitOfBytesat(magnitude, ix) !== 0) { | |
| return true; | |
| } | |
| } | |
| if (((SHL(digitOfBytesat(magnitude, lastByteIx), leftShift)) & 255) !== 0) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| /* Precondition: bytesOop is not anInteger and a bytes object. */ | |
| /* Function #byteSizeOf: is used by the interpreter, be careful with name | |
| clashes... */ | |
| function byteSizeOfBytes(bytesOop) { | |
| return SIZEOF(bytesOop); | |
| } | |
| /* Attention: this method invalidates all oop's! Only newBytes is valid at return. */ | |
| /* Does not normalize. */ | |
| function bytesgrowTo(aBytesObject, newLen) { | |
| var oldLen; | |
| var copyLen; | |
| var newBytes; | |
| newBytes = interpreterProxy.instantiateClassindexableSize(CLASSOF(aBytesObject), newLen); | |
| ; | |
| oldLen = BYTESIZEOF(aBytesObject); | |
| if (oldLen < newLen) { | |
| copyLen = oldLen; | |
| } else { | |
| copyLen = newLen; | |
| } | |
| cDigitCopyFromtolen(aBytesObject.bytes, newBytes.bytes, copyLen); | |
| return newBytes; | |
| } | |
| /* Attention: this method invalidates all oop's! Only newBytes is valid at return. */ | |
| function bytesOrIntgrowTo(oop, len) { | |
| var sq_class; | |
| var val; | |
| var newBytes; | |
| if (typeof oop === "number") { | |
| val = oop; | |
| if (val < 0) { | |
| sq_class = interpreterProxy.classLargeNegativeInteger(); | |
| } else { | |
| sq_class = interpreterProxy.classLargePositiveInteger(); | |
| } | |
| newBytes = interpreterProxy.instantiateClassindexableSize(sq_class, len); | |
| cCopyIntValtoBytes(val, newBytes); | |
| } else { | |
| newBytes = bytesgrowTo(oop, len); | |
| } | |
| return newBytes; | |
| } | |
| function cCopyIntValtoBytes(val, bytes) { | |
| var pByte; | |
| var ix; | |
| var ixLimiT; | |
| pByte = bytes.bytes; | |
| for (ix = 1, ixLimiT = cDigitLengthOfCSI(val); ix <= ixLimiT; ix++) { | |
| pByte[ix - 1] = cDigitOfCSIat(val, ix); | |
| } | |
| } | |
| /* pByteRes len = longLen; returns over.. */ | |
| function cDigitAddlenwithleninto(pByteShort, shortLen, pByteLong, longLen, pByteRes) { | |
| var i; | |
| var limit; | |
| var accum; | |
| accum = 0; | |
| limit = shortLen - 1; | |
| for (i = 0; i <= limit; i++) { | |
| accum = ((accum >>> 8) + pByteShort[i]) + pByteLong[i]; | |
| pByteRes[i] = (accum & 255); | |
| } | |
| limit = longLen - 1; | |
| for (i = shortLen; i <= limit; i++) { | |
| accum = (accum >>> 8) + pByteLong[i]; | |
| pByteRes[i] = (accum & 255); | |
| } | |
| return accum >>> 8; | |
| } | |
| /* Precondition: pFirst len = pSecond len. */ | |
| function cDigitComparewithlen(pFirst, pSecond, len) { | |
| var firstDigit; | |
| var secondDigit; | |
| var ix; | |
| ix = len - 1; | |
| while (ix >= 0) { | |
| if (((secondDigit = pSecond[ix])) !== ((firstDigit = pFirst[ix]))) { | |
| if (secondDigit < firstDigit) { | |
| return 1; | |
| } else { | |
| return -1; | |
| } | |
| } | |
| --ix; | |
| } | |
| return 0; | |
| } | |
| function cDigitCopyFromtolen(pFrom, pTo, len) { | |
| var limit; | |
| var i; | |
| ; | |
| limit = len - 1; | |
| for (i = 0; i <= limit; i++) { | |
| pTo[i] = pFrom[i]; | |
| } | |
| return 0; | |
| } | |
| function cDigitDivlenremlenquolen(pDiv, divLen, pRem, remLen, pQuo, quoLen) { | |
| var b; | |
| var q; | |
| var a; | |
| var dnh; | |
| var lo; | |
| var hi; | |
| var r3; | |
| var mul; | |
| var cond; | |
| var l; | |
| var k; | |
| var j; | |
| var i; | |
| var dl; | |
| var ql; | |
| var r1r2; | |
| var dh; | |
| var t; | |
| /* Last actual byte of data (ST ix) */ | |
| dl = divLen - 1; | |
| ql = quoLen; | |
| dh = pDiv[dl - 1]; | |
| if (dl === 1) { | |
| dnh = 0; | |
| } else { | |
| dnh = pDiv[dl - 2]; | |
| } | |
| for (k = 1; k <= ql; k++) { | |
| /* maintain quo*arg+rem=self */ | |
| /* Estimate rem/div by dividing the leading two digits of rem by dh. */ | |
| /* The estimate is q = qhi*16r100+qlo, where qhi and qlo are unsigned char. */ | |
| /* r1 := rem digitAt: j. */ | |
| j = (remLen + 1) - k; | |
| if (pRem[j - 1] === dh) { | |
| q = 255; | |
| } else { | |
| /* Compute q = (r1,r2)//dh, t = (r1,r2)\\dh. */ | |
| /* r2 := (rem digitAt: j - 2). */ | |
| r1r2 = pRem[j - 1]; | |
| r1r2 = (r1r2 << 8) + pRem[j - 2]; | |
| t = MOD(r1r2, dh); | |
| /* Next compute (hi,lo) := q*dnh */ | |
| q = DIV(r1r2, dh); | |
| mul = q * dnh; | |
| hi = mul >>> 8; | |
| /* Correct overestimate of q. | |
| Max of 2 iterations through loop -- see Knuth vol. 2 */ | |
| lo = mul & 255; | |
| if (j < 3) { | |
| r3 = 0; | |
| } else { | |
| r3 = pRem[j - 3]; | |
| } | |
| while (true) { | |
| if ((t < hi) || ((t === hi) && (r3 < lo))) { | |
| /* i.e. (t,r3) < (hi,lo) */ | |
| --q; | |
| if (lo < dnh) { | |
| --hi; | |
| lo = (lo + 256) - dnh; | |
| } else { | |
| lo -= dnh; | |
| } | |
| cond = hi >= dh; | |
| } else { | |
| cond = false; | |
| } | |
| if (!(cond)) break; | |
| hi -= dh; | |
| } | |
| } | |
| l = j - dl; | |
| a = 0; | |
| for (i = 1; i <= divLen; i++) { | |
| hi = pDiv[i - 1] * (q >>> 8); | |
| lo = pDiv[i - 1] * (q & 255); | |
| b = (pRem[l - 1] - a) - (lo & 255); | |
| pRem[l - 1] = (b & 255); | |
| /* This is a possible replacement to simulate arithmetic shift (preserving sign of b) */ | |
| /* b := b >> 8 bitOr: (0 - (b >> ((interpreterProxy sizeof: b)*8 */ | |
| /* CHAR_BIT */ | |
| /* -1)) << 8). */ | |
| b = b >> 8; | |
| a = (hi + (lo >>> 8)) - b; | |
| ++l; | |
| } | |
| if (a > 0) { | |
| /* Add div back into rem, decrease q by 1 */ | |
| --q; | |
| l = j - dl; | |
| a = 0; | |
| for (i = 1; i <= divLen; i++) { | |
| a = ((a >>> 8) + pRem[l - 1]) + pDiv[i - 1]; | |
| pRem[l - 1] = (a & 255); | |
| ++l; | |
| } | |
| } | |
| pQuo[quoLen - k] = q; | |
| } | |
| return 0; | |
| } | |
| /* Answer the index (in bits) of the high order bit of the receiver, or zero if the | |
| receiver is zero. This method is allowed (and needed) for | |
| LargeNegativeIntegers as well, since Squeak's LargeIntegers are | |
| sign/magnitude. */ | |
| function cDigitHighBitlen(pByte, len) { | |
| var lastDigit; | |
| var realLength; | |
| realLength = len; | |
| while (((lastDigit = pByte[realLength - 1])) === 0) { | |
| if (((--realLength)) === 0) { | |
| return 0; | |
| } | |
| } | |
| return cHighBit(lastDigit) + (8 * (realLength - 1)); | |
| } | |
| /* Answer the number of indexable fields of a CSmallInteger. This value is | |
| the same as the largest legal subscript. */ | |
| function cDigitLengthOfCSI(csi) { | |
| if ((csi < 256) && (csi > -256)) { | |
| return 1; | |
| } | |
| if ((csi < 65536) && (csi > -65536)) { | |
| return 2; | |
| } | |
| if ((csi < 16777216) && (csi > -16777216)) { | |
| return 3; | |
| } | |
| return 4; | |
| } | |
| /* C indexed! */ | |
| function cDigitLshiftfromlentolen(shiftCount, pFrom, lenFrom, pTo, lenTo) { | |
| var digitShift; | |
| var carry; | |
| var digit; | |
| var i; | |
| var bitShift; | |
| var rshift; | |
| var limit; | |
| digitShift = shiftCount >> 3; | |
| bitShift = MOD(shiftCount, 8); | |
| limit = digitShift - 1; | |
| for (i = 0; i <= limit; i++) { | |
| pTo[i] = 0; | |
| } | |
| if (bitShift === 0) { | |
| /* Fast version for digit-aligned shifts */ | |
| /* C indexed! */ | |
| return cDigitReplacefromtowithstartingAt(pTo, digitShift, lenTo - 1, pFrom, 0); | |
| } | |
| rshift = 8 - bitShift; | |
| carry = 0; | |
| limit = lenFrom - 1; | |
| for (i = 0; i <= limit; i++) { | |
| digit = pFrom[i]; | |
| pTo[i + digitShift] = ((carry | (SHL(digit, bitShift))) & 255); | |
| carry = SHR(digit, rshift); | |
| } | |
| if (carry !== 0) { | |
| pTo[lenTo - 1] = carry; | |
| } | |
| return 0; | |
| } | |
| function cDigitMontgomerylentimeslenmodulolenmInvModBinto(pBytesFirst, firstLen, pBytesSecond, secondLen, pBytesThird, thirdLen, mInv, pBytesRes) { | |
| var k; | |
| var i; | |
| var lastByte; | |
| var limit3; | |
| var limit2; | |
| var limit1; | |
| var u; | |
| var accum; | |
| limit1 = firstLen - 1; | |
| limit2 = secondLen - 1; | |
| limit3 = thirdLen - 1; | |
| lastByte = 0; | |
| for (i = 0; i <= limit1; i++) { | |
| accum = pBytesRes[0] + (pBytesFirst[i] * pBytesSecond[0]); | |
| u = (accum * mInv) & 255; | |
| accum += u * pBytesThird[0]; | |
| for (k = 1; k <= limit2; k++) { | |
| accum = (((accum >>> 8) + pBytesRes[k]) + (pBytesFirst[i] * pBytesSecond[k])) + (u * pBytesThird[k]); | |
| pBytesRes[k - 1] = (accum & 255); | |
| } | |
| for (k = secondLen; k <= limit3; k++) { | |
| accum = ((accum >>> 8) + pBytesRes[k]) + (u * pBytesThird[k]); | |
| pBytesRes[k - 1] = (accum & 255); | |
| } | |
| accum = (accum >>> 8) + lastByte; | |
| pBytesRes[limit3] = (accum & 255); | |
| lastByte = accum >>> 8; | |
| } | |
| for (i = firstLen; i <= limit3; i++) { | |
| accum = pBytesRes[0]; | |
| u = (accum * mInv) & 255; | |
| accum += u * pBytesThird[0]; | |
| for (k = 1; k <= limit3; k++) { | |
| accum = ((accum >>> 8) + pBytesRes[k]) + (u * pBytesThird[k]); | |
| pBytesRes[k - 1] = (accum & 255); | |
| } | |
| accum = (accum >>> 8) + lastByte; | |
| pBytesRes[limit3] = (accum & 255); | |
| lastByte = accum >>> 8; | |
| } | |
| if (!((lastByte === 0) && (cDigitComparewithlen(pBytesThird, pBytesRes, thirdLen) === 1))) { | |
| /* self cDigitSub: pBytesThird len: thirdLen with: pBytesRes len: thirdLen into: pBytesRes */ | |
| accum = 0; | |
| for (i = 0; i <= limit3; i++) { | |
| accum = (accum + pBytesRes[i]) - pBytesThird[i]; | |
| pBytesRes[i] = (accum & 255); | |
| accum = accum >> 8; | |
| } | |
| } | |
| } | |
| function cDigitMultiplylenwithleninto(pByteShort, shortLen, pByteLong, longLen, pByteRes) { | |
| var ab; | |
| var j; | |
| var digit; | |
| var carry; | |
| var i; | |
| var limitLong; | |
| var k; | |
| var limitShort; | |
| if ((shortLen === 1) && (pByteShort[0] === 0)) { | |
| return 0; | |
| } | |
| if ((longLen === 1) && (pByteLong[0] === 0)) { | |
| return 0; | |
| } | |
| limitShort = shortLen - 1; | |
| limitLong = longLen - 1; | |
| for (i = 0; i <= limitShort; i++) { | |
| if (((digit = pByteShort[i])) !== 0) { | |
| k = i; | |
| /* Loop invariant: 0<=carry<=0377, k=i+j-1 (ST) */ | |
| /* -> Loop invariant: 0<=carry<=0377, k=i+j (C) (?) */ | |
| carry = 0; | |
| for (j = 0; j <= limitLong; j++) { | |
| ab = pByteLong[j]; | |
| ab = ((ab * digit) + carry) + pByteRes[k]; | |
| carry = ab >>> 8; | |
| pByteRes[k] = (ab & 255); | |
| ++k; | |
| } | |
| pByteRes[k] = carry; | |
| } | |
| } | |
| return 0; | |
| } | |
| /* Answer the value of an indexable field in the receiver. | |
| LargePositiveInteger uses bytes of base two number, and each is a | |
| 'digit' base 256. */ | |
| /* ST indexed! */ | |
| function cDigitOfCSIat(csi, ix) { | |
| if (ix < 1) { | |
| interpreterProxy.primitiveFail(); | |
| } | |
| if (ix > 4) { | |
| return 0; | |
| } | |
| if (csi < 0) { | |
| ; | |
| return (SHR((0 - csi), ((ix - 1) * 8))) & 255; | |
| } else { | |
| return (SHR(csi, ((ix - 1) * 8))) & 255; | |
| } | |
| } | |
| /* pByteRes len = longLen. */ | |
| function cDigitOpshortlenlongleninto(opIndex, pByteShort, shortLen, pByteLong, longLen, pByteRes) { | |
| var i; | |
| var limit; | |
| limit = shortLen - 1; | |
| if (opIndex === andOpIndex) { | |
| for (i = 0; i <= limit; i++) { | |
| pByteRes[i] = (pByteShort[i] & pByteLong[i]); | |
| } | |
| limit = longLen - 1; | |
| for (i = shortLen; i <= limit; i++) { | |
| pByteRes[i] = 0; | |
| } | |
| return 0; | |
| } | |
| if (opIndex === orOpIndex) { | |
| for (i = 0; i <= limit; i++) { | |
| pByteRes[i] = (pByteShort[i] | pByteLong[i]); | |
| } | |
| limit = longLen - 1; | |
| for (i = shortLen; i <= limit; i++) { | |
| pByteRes[i] = pByteLong[i]; | |
| } | |
| return 0; | |
| } | |
| if (opIndex === xorOpIndex) { | |
| for (i = 0; i <= limit; i++) { | |
| pByteRes[i] = (pByteShort[i] ^ pByteLong[i]); | |
| } | |
| limit = longLen - 1; | |
| for (i = shortLen; i <= limit; i++) { | |
| pByteRes[i] = pByteLong[i]; | |
| } | |
| return 0; | |
| } | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| /* C indexed! */ | |
| function cDigitReplacefromtowithstartingAt(pTo, start, stop, pFrom, repStart) { | |
| return function() { | |
| // inlining self cDigitCopyFrom: pFrom + repStart to: pTo + start len: stop - start + 1 | |
| var len = stop - start + 1; | |
| for (var i = 0; i < len; i++) { | |
| pTo[i + start] = pFrom[i + repStart]; | |
| } | |
| return 0; | |
| }(); | |
| ; | |
| } | |
| function cDigitRshiftfromlentolen(shiftCount, pFrom, fromLen, pTo, toLen) { | |
| var j; | |
| var digitShift; | |
| var carry; | |
| var digit; | |
| var bitShift; | |
| var leftShift; | |
| var limit; | |
| var start; | |
| digitShift = shiftCount >> 3; | |
| bitShift = MOD(shiftCount, 8); | |
| if (bitShift === 0) { | |
| /* Fast version for byte-aligned shifts */ | |
| /* C indexed! */ | |
| return cDigitReplacefromtowithstartingAt(pTo, 0, toLen - 1, pFrom, digitShift); | |
| } | |
| leftShift = 8 - bitShift; | |
| carry = SHR(pFrom[digitShift], bitShift); | |
| start = digitShift + 1; | |
| limit = fromLen - 1; | |
| for (j = start; j <= limit; j++) { | |
| digit = pFrom[j]; | |
| pTo[j - start] = ((carry | (SHL(digit, leftShift))) & 255); | |
| carry = SHR(digit, bitShift); | |
| } | |
| if (carry !== 0) { | |
| pTo[toLen - 1] = carry; | |
| } | |
| return 0; | |
| } | |
| function cDigitSublenwithleninto(pByteSmall, smallLen, pByteLarge, largeLen, pByteRes) { | |
| var i; | |
| var z; | |
| /* Loop invariant is -1<=z<=0 */ | |
| z = 0; | |
| for (i = 0; i <= (smallLen - 1); i++) { | |
| z = (z + pByteLarge[i]) - pByteSmall[i]; | |
| pByteRes[i] = (z & 255); | |
| z = z >> 8; | |
| } | |
| for (i = smallLen; i <= (largeLen - 1); i++) { | |
| z += pByteLarge[i]; | |
| pByteRes[i] = (z & 255); | |
| z = z >> 8; | |
| } | |
| } | |
| /* Answer the index of the high order bit of the argument, or zero if the | |
| argument is zero. */ | |
| /* For 64 bit uints there could be added a 32-shift. */ | |
| function cHighBit(uint) { | |
| var shifted; | |
| var bitNo; | |
| shifted = uint; | |
| bitNo = 0; | |
| if (!(shifted < (1 << 16))) { | |
| shifted = shifted >>> 16; | |
| bitNo += 16; | |
| } | |
| if (!(shifted < (1 << 8))) { | |
| shifted = shifted >>> 8; | |
| bitNo += 8; | |
| } | |
| if (!(shifted < (1 << 4))) { | |
| shifted = shifted >>> 4; | |
| bitNo += 4; | |
| } | |
| if (!(shifted < (1 << 2))) { | |
| shifted = shifted >>> 2; | |
| bitNo += 2; | |
| } | |
| if (!(shifted < (1 << 1))) { | |
| shifted = shifted >>> 1; | |
| ++bitNo; | |
| } | |
| return bitNo + shifted; | |
| } | |
| /* anOop has to be a SmallInteger! */ | |
| function createLargeFromSmallInteger(anOop) { | |
| var size; | |
| var res; | |
| var pByte; | |
| var ix; | |
| var sq_class; | |
| var val; | |
| val = anOop; | |
| if (val < 0) { | |
| sq_class = interpreterProxy.classLargeNegativeInteger(); | |
| } else { | |
| sq_class = interpreterProxy.classLargePositiveInteger(); | |
| } | |
| size = cDigitLengthOfCSI(val); | |
| res = interpreterProxy.instantiateClassindexableSize(sq_class, size); | |
| pByte = res.bytes; | |
| for (ix = 1; ix <= size; ix++) { | |
| pByte[ix - 1] = cDigitOfCSIat(val, ix); | |
| } | |
| return res; | |
| } | |
| /* Attention: this method invalidates all oop's! Only newBytes is valid at return. */ | |
| /* Does not normalize. */ | |
| function digitLshift(aBytesOop, shiftCount) { | |
| var newLen; | |
| var oldLen; | |
| var newBytes; | |
| var highBit; | |
| oldLen = BYTESIZEOF(aBytesOop); | |
| if (((highBit = cDigitHighBitlen(aBytesOop.bytes, oldLen))) === 0) { | |
| return 0; | |
| } | |
| newLen = ((highBit + shiftCount) + 7) >> 3; | |
| newBytes = interpreterProxy.instantiateClassindexableSize(CLASSOF(aBytesOop), newLen); | |
| ; | |
| cDigitLshiftfromlentolen(shiftCount, aBytesOop.bytes, oldLen, newBytes.bytes, newLen); | |
| return newBytes; | |
| } | |
| /* Attention: this method invalidates all oop's! Only newBytes is valid at return. */ | |
| /* Shift right shiftCount bits, 0<=shiftCount. | |
| Discard all digits beyond a, and all zeroes at or below a. */ | |
| /* Does not normalize. */ | |
| function digitRshiftlookfirst(aBytesOop, shiftCount, a) { | |
| var newOop; | |
| var oldDigitLen; | |
| var newByteLen; | |
| var newBitLen; | |
| var oldBitLen; | |
| oldBitLen = cDigitHighBitlen(aBytesOop.bytes, a); | |
| oldDigitLen = (oldBitLen + 7) >> 3; | |
| newBitLen = oldBitLen - shiftCount; | |
| if (newBitLen <= 0) { | |
| /* All bits lost */ | |
| return interpreterProxy.instantiateClassindexableSize(CLASSOF(aBytesOop), 0); | |
| } | |
| newByteLen = (newBitLen + 7) >> 3; | |
| newOop = interpreterProxy.instantiateClassindexableSize(CLASSOF(aBytesOop), newByteLen); | |
| ; | |
| cDigitRshiftfromlentolen(shiftCount, aBytesOop.bytes, oldDigitLen, newOop.bytes, newByteLen); | |
| return newOop; | |
| } | |
| /* Does not need to normalize! */ | |
| function digitAddLargewith(firstInteger, secondInteger) { | |
| var sum; | |
| var shortLen; | |
| var over; | |
| var shortInt; | |
| var resClass; | |
| var newSum; | |
| var longLen; | |
| var firstLen; | |
| var secondLen; | |
| var longInt; | |
| firstLen = BYTESIZEOF(firstInteger); | |
| secondLen = BYTESIZEOF(secondInteger); | |
| resClass = CLASSOF(firstInteger); | |
| if (firstLen <= secondLen) { | |
| shortInt = firstInteger; | |
| shortLen = firstLen; | |
| longInt = secondInteger; | |
| longLen = secondLen; | |
| } else { | |
| shortInt = secondInteger; | |
| shortLen = secondLen; | |
| longInt = firstInteger; | |
| longLen = firstLen; | |
| } | |
| sum = interpreterProxy.instantiateClassindexableSize(resClass, longLen); | |
| ; | |
| over = cDigitAddlenwithleninto(shortInt.bytes, shortLen, longInt.bytes, longLen, sum.bytes); | |
| if (over > 0) { | |
| /* sum := sum growby: 1. */ | |
| newSum = interpreterProxy.instantiateClassindexableSize(resClass, longLen + 1); | |
| ; | |
| cDigitCopyFromtolen(sum.bytes, newSum.bytes, longLen); | |
| /* C index! */ | |
| sum = newSum; | |
| sum.bytes[longLen] = over; | |
| } | |
| return sum; | |
| } | |
| /* Bit logic here is only implemented for positive integers or Zero; | |
| if rec or arg is negative, it fails. */ | |
| function digitBitLogicwithopIndex(firstInteger, secondInteger, opIx) { | |
| var shortLen; | |
| var shortLarge; | |
| var firstLarge; | |
| var secondLarge; | |
| var longLen; | |
| var longLarge; | |
| var firstLen; | |
| var secondLen; | |
| var result; | |
| if (typeof firstInteger === "number") { | |
| if (firstInteger < 0) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| if (CLASSOF(firstInteger) === interpreterProxy.classLargeNegativeInteger()) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| if (secondInteger < 0) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| if (CLASSOF(secondInteger) === interpreterProxy.classLargeNegativeInteger()) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| secondLarge = secondInteger; | |
| } | |
| firstLen = BYTESIZEOF(firstLarge); | |
| secondLen = BYTESIZEOF(secondLarge); | |
| if (firstLen < secondLen) { | |
| shortLen = firstLen; | |
| shortLarge = firstLarge; | |
| longLen = secondLen; | |
| longLarge = secondLarge; | |
| } else { | |
| shortLen = secondLen; | |
| shortLarge = secondLarge; | |
| longLen = firstLen; | |
| longLarge = firstLarge; | |
| } | |
| result = interpreterProxy.instantiateClassindexableSize(interpreterProxy.classLargePositiveInteger(), longLen); | |
| ; | |
| cDigitOpshortlenlongleninto(opIx, shortLarge.bytes, shortLen, longLarge.bytes, longLen, result.bytes); | |
| if (interpreterProxy.failed()) { | |
| return 0; | |
| } | |
| return normalizePositive(result); | |
| } | |
| /* Compare the magnitude of firstInteger with that of secondInteger. | |
| Return a code of 1, 0, -1 for firstInteger >, = , < secondInteger */ | |
| function digitCompareLargewith(firstInteger, secondInteger) { | |
| var secondLen; | |
| var firstLen; | |
| firstLen = BYTESIZEOF(firstInteger); | |
| secondLen = BYTESIZEOF(secondInteger); | |
| if (secondLen !== firstLen) { | |
| if (secondLen > firstLen) { | |
| return -1; | |
| } else { | |
| return 1; | |
| } | |
| } | |
| return cDigitComparewithlen(firstInteger.bytes, secondInteger.bytes, firstLen); | |
| } | |
| /* Does not normalize. */ | |
| /* Division by zero has to be checked in caller. */ | |
| function digitDivLargewithnegative(firstInteger, secondInteger, neg) { | |
| var resultClass; | |
| var result; | |
| var rem; | |
| var div; | |
| var quo; | |
| var d; | |
| var l; | |
| var secondLen; | |
| var firstLen; | |
| firstLen = BYTESIZEOF(firstInteger); | |
| secondLen = BYTESIZEOF(secondInteger); | |
| if (neg) { | |
| resultClass = interpreterProxy.classLargeNegativeInteger(); | |
| } else { | |
| resultClass = interpreterProxy.classLargePositiveInteger(); | |
| } | |
| l = (firstLen - secondLen) + 1; | |
| if (l <= 0) { | |
| result = interpreterProxy.instantiateClassindexableSize(interpreterProxy.classArray(), 2); | |
| ; | |
| interpreterProxy.stObjectatput(result,1,0); | |
| interpreterProxy.stObjectatput(result,2,firstInteger); | |
| return result; | |
| } | |
| d = 8 - cHighBit(unsafeByteOfat(secondInteger, secondLen)); | |
| div = digitLshift(secondInteger, d); | |
| div = bytesOrIntgrowTo(div, digitLength(div) + 1); | |
| ; | |
| rem = digitLshift(firstInteger, d); | |
| if (digitLength(rem) === firstLen) { | |
| rem = bytesOrIntgrowTo(rem, firstLen + 1); | |
| } | |
| ; | |
| quo = interpreterProxy.instantiateClassindexableSize(resultClass, l); | |
| ; | |
| cDigitDivlenremlenquolen(div.bytes, digitLength(div), rem.bytes, digitLength(rem), quo.bytes, digitLength(quo)); | |
| rem = digitRshiftlookfirst(rem, d, digitLength(div) - 1); | |
| ; | |
| result = interpreterProxy.instantiateClassindexableSize(interpreterProxy.classArray(), 2); | |
| ; | |
| interpreterProxy.stObjectatput(result,1,quo); | |
| interpreterProxy.stObjectatput(result,2,rem); | |
| return result; | |
| } | |
| function digitLength(oop) { | |
| if (typeof oop === "number") { | |
| return cDigitLengthOfCSI(oop); | |
| } else { | |
| return BYTESIZEOF(oop); | |
| } | |
| } | |
| function digitMontgomerytimesmodulomInvModB(firstLarge, secondLarge, thirdLarge, mInv) { | |
| var prod; | |
| var thirdLen; | |
| var firstLen; | |
| var secondLen; | |
| firstLen = BYTESIZEOF(firstLarge); | |
| secondLen = BYTESIZEOF(secondLarge); | |
| thirdLen = BYTESIZEOF(thirdLarge); | |
| if (!(firstLen <= thirdLen)) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| if (!(secondLen <= thirdLen)) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| if (!((mInv >= 0) && (mInv <= 255))) { | |
| return interpreterProxy.primitiveFail(); | |
| } | |
| prod = interpreterProxy.instantiateClassindexableSize(interpreterProxy.classLargePositiveInteger(), thirdLen); | |
| ; | |
| cDigitMontgomerylentimeslenmodulolenmInvModBinto(firstLarge.bytes, firstLen, secondLarge.bytes, secondLen, thirdLarge.bytes, thirdLen, mInv, prod.bytes); | |
| return normalizePositive(prod); | |
| } | |
| /* Normalizes. */ | |
| function digitMultiplyLargewithnegative(firstInteger, secondInteger, neg) { | |
| var longInt; | |
| var resultClass; | |
| var shortLen; | |
| var shortInt; | |
| var longLen; | |
| var prod; | |
| var secondLen; | |
| var firstLen; | |
| firstLen = BYTESIZEOF(firstInteger); | |
| secondLen = BYTESIZEOF(secondInteger); | |
| if (firstLen <= secondLen) { | |
| shortInt = firstInteger; | |
| shortLen = firstLen; | |
| longInt = secondInteger; | |
| longLen = secondLen; | |
| } else { | |
| shortInt = secondInteger; | |
| shortLen = secondLen; | |
| longInt = firstInteger; | |
| longLen = firstLen; | |
| } | |
| if (neg) { | |
| resultClass = interpreterProxy.classLargeNegativeInteger(); | |
| } else { | |
| resultClass = interpreterProxy.classLargePositiveInteger(); | |
| } | |
| prod = interpreterProxy.instantiateClassindexableSize(resultClass, longLen + shortLen); | |
| ; | |
| cDigitMultiplylenwithleninto(shortInt.bytes, shortLen, longInt.bytes, longLen, prod.bytes); | |
| return normalize(prod); | |
| } | |
| /* Argument has to be aLargeInteger! */ | |
| function digitOfBytesat(aBytesOop, ix) { | |
| if (ix > BYTESIZEOF(aBytesOop)) { | |
| return 0; | |
| } else { | |
| return unsafeByteOfat(aBytesOop, ix); | |
| } | |
| } | |
| /* Normalizes. */ | |
| function digitSubLargewith(firstInteger, secondInteger) { | |
| var smallerLen; | |
| var larger; | |
| var res; | |
| var smaller; | |
| var resLen; | |
| var largerLen; | |
| var firstNeg; | |
| var firstLen; | |
| var secondLen; | |
| var neg; | |
| firstNeg = CLASSOF(firstInteger) === interpreterProxy.classLargeNegativeInteger(); | |
| firstLen = BYTESIZEOF(firstInteger); | |
| secondLen = BYTESIZEOF(secondInteger); | |
| if (firstLen === secondLen) { | |
| while ((firstLen > 1) && (digitOfBytesat(firstInteger, firstLen) === digitOfBytesat(secondInteger, firstLen))) { | |
| --firstLen; | |
| } | |
| secondLen = firstLen; | |
| } | |
| if ((firstLen < secondLen) || ((firstLen === secondLen) && (digitOfBytesat(firstInteger, firstLen) < digitOfBytesat(secondInteger, firstLen)))) { | |
| larger = secondInteger; | |
| largerLen = secondLen; | |
| smaller = firstInteger; | |
| smallerLen = firstLen; | |
| neg = firstNeg === false; | |
| } else { | |
| larger = firstInteger; | |
| largerLen = firstLen; | |
| smaller = secondInteger; | |
| smallerLen = secondLen; | |
| neg = firstNeg; | |
| } | |
| resLen = largerLen; | |
| res = interpreterProxy.instantiateClassindexableSize((neg | |
| ? interpreterProxy.classLargeNegativeInteger() | |
| : interpreterProxy.classLargePositiveInteger()), resLen); | |
| ; | |
| cDigitSublenwithleninto(smaller.bytes, smallerLen, larger.bytes, largerLen, res.bytes); | |
| return (neg | |
| ? normalizeNegative(res) | |
| : normalizePositive(res)); | |
| } | |
| /* Note: This is hardcoded so it can be run from Squeak. | |
| The module name is used for validating a module *after* | |
| it is loaded to check if it does really contain the module | |
| we're thinking it contains. This is important! */ | |
| function getModuleName() { | |
| return moduleName; | |
| } | |
| function halt() { | |
| ; | |
| } | |
| function highBitOfBytes(aBytesOop) { | |
| return cDigitHighBitlen(aBytesOop.bytes, BYTESIZEOF(aBytesOop)); | |
| } | |
| function isNormalized(anInteger) { | |
| var ix; | |
| var len; | |
| var sLen; | |
| var minVal; | |
| var maxVal; | |
| if (typeof anInteger === "number") { | |
| return true; | |
| } | |
| len = digitLength(anInteger); | |
| if (len === 0) { | |
| return false; | |
| } | |
| if (unsafeByteOfat(anInteger, len) === 0) { | |
| return false; | |
| } | |
| /* maximal digitLength of aSmallInteger */ | |
| sLen = 4; | |
| if (len > sLen) { | |
| return true; | |
| } | |
| if (len < sLen) { | |
| return false; | |
| } | |
| if (CLASSOF(anInteger) === interpreterProxy.classLargePositiveInteger()) { | |
| /* SmallInteger maxVal */ | |
| /* all bytes of maxVal but the highest one are just FF's */ | |
| maxVal = 1073741823; | |
| return unsafeByteOfat(anInteger, sLen) > cDigitOfCSIat(maxVal, sLen); | |
| } else { | |
| /* SmallInteger minVal */ | |
| /* all bytes of minVal but the highest one are just 00's */ | |
| minVal = -1073741824; | |
| if (unsafeByteOfat(anInteger, sLen) < cDigitOfCSIat(minVal, sLen)) { | |
| return false; | |
| } else { | |
| /* if just one digit differs, then anInteger < minval (the corresponding digit byte is greater!) | |
| and therefore a LargeNegativeInteger */ | |
| for (ix = 1; ix <= sLen; ix++) { | |
| if (unsafeByteOfat(anInteger, ix) !== cDigitOfCSIat(minVal, ix)) { | |
| return true; | |
| } | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| function msg(s) { | |
| console.log(moduleName + ": " + s); | |
| } | |
| /* Check for leading zeroes and return shortened copy if so. */ | |
| function normalize(aLargeInteger) { | |
| // missing DebugCode; | |
| if (CLASSOF(aLargeInteger) === interpreterProxy.classLargePositiveInteger()) { | |
| return normalizePositive(aLargeInteger); | |
| } else { | |
| return normalizeNegative(aLargeInteger); | |
| } | |
| } | |
| /* Check for leading zeroes and return shortened copy if so. */ | |
| /* First establish len = significant length. */ | |
| function normalizeNegative(aLargeNegativeInteger) { | |
| var i; | |
| var len; | |
| var sLen; | |
| var minVal; | |
| var oldLen; | |
| var val; | |
| len = (oldLen = digitLength(aLargeNegativeInteger)); | |
| while ((len !== 0) && (unsafeByteOfat(aLargeNegativeInteger, len) === 0)) { | |
| --len; | |
| } | |
| if (len === 0) { | |
| return 0; | |
| } | |
| /* SmallInteger minVal digitLength */ | |
| sLen = 4; | |
| if (len <= sLen) { | |
| /* SmallInteger minVal */ | |
| minVal = -1073741824; | |
| if ((len < sLen) || (digitOfBytesat(aLargeNegativeInteger, sLen) < cDigitOfCSIat(minVal, sLen))) { | |
| /* If high digit less, then can be small */ | |
| val = 0; | |
| for (i = len; i >= 1; i += -1) { | |
| val = (val * 256) - unsafeByteOfat(aLargeNegativeInteger, i); | |
| } | |
| return val; | |
| } | |
| for (i = 1; i <= sLen; i++) { | |
| /* If all digits same, then = minVal (sr: minVal digits 1 to 3 are | |
| 0) */ | |
| if (digitOfBytesat(aLargeNegativeInteger, i) !== cDigitOfCSIat(minVal, i)) { | |
| /* Not so; return self shortened */ | |
| if (len < oldLen) { | |
| /* ^ self growto: len */ | |
| return bytesgrowTo(aLargeNegativeInteger, len); | |
| } else { | |
| return aLargeNegativeInteger; | |
| } | |
| } | |
| } | |
| return minVal; | |
| } | |
| if (len < oldLen) { | |
| /* ^ self growto: len */ | |
| return bytesgrowTo(aLargeNegativeInteger, len); | |
| } else { | |
| return aLargeNegativeInteger; | |
| } | |
| } | |
| /* Check for leading zeroes and return shortened copy if so. */ | |
| /* First establish len = significant length. */ | |
| function normalizePositive(aLargePositiveInteger) { | |
| var i; | |
| var len; | |
| var sLen; | |
| var val; | |
| var oldLen; | |
| len = (oldLen = digitLength(aLargePositiveInteger)); | |
| while ((len !== 0) && (unsafeByteOfat(aLargePositiveInteger, len) === 0)) { | |
| --len; | |
| } | |
| if (len === 0) { | |
| return 0; | |
| } | |
| /* SmallInteger maxVal digitLength. */ | |
| sLen = 4; | |
| if ((len <= sLen) && (digitOfBytesat(aLargePositiveInteger, sLen) <= cDigitOfCSIat(1073741823, sLen))) { | |
| /* If so, return its SmallInt value */ | |
| val = 0; | |
| for (i = len; i >= 1; i += -1) { | |
| val = (val * 256) + unsafeByteOfat(aLargePositiveInteger, i); | |
| } | |
| return val; | |
| } | |
| if (len < oldLen) { | |
| /* ^ self growto: len */ | |
| return bytesgrowTo(aLargePositiveInteger, len); | |
| } else { | |
| return aLargePositiveInteger; | |
| } | |
| } | |
| function primAnyBitFromTo() { | |
| var integer; | |
| var large; | |
| var from; | |
| var to; | |
| var _return_value; | |
| from = interpreterProxy.stackIntegerValue(1); | |
| to = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| integer = interpreterProxy.stackValue(2); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof integer === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| large = createLargeFromSmallInteger(integer); | |
| } else { | |
| large = integer; | |
| } | |
| _return_value = (anyBitOfBytesfromto(large, from, to)? interpreterProxy.trueObject() : interpreterProxy.falseObject()); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| /* Converts a SmallInteger into a - non normalized! - LargeInteger; | |
| aLargeInteger will be returned unchanged. */ | |
| /* Do not check for forced fail, because we need this conversion to test the | |
| plugin in ST during forced fail, too. */ | |
| function primAsLargeInteger() { | |
| var anInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| anInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof anInteger === "number") { | |
| _return_value = createLargeFromSmallInteger(anInteger); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, anInteger); | |
| return null; | |
| } | |
| } | |
| /* If calling this primitive fails, then C module does not exist. Do not check for forced fail, because we want to know if module exists during forced fail, too. */ | |
| function primCheckIfCModuleExists() { | |
| var _return_value; | |
| _return_value = (true? interpreterProxy.trueObject() : interpreterProxy.falseObject()); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(1, _return_value); | |
| return null; | |
| } | |
| function _primDigitBitShift() { | |
| var rShift; | |
| var aLarge; | |
| var anInteger; | |
| var shiftCount; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| anInteger = interpreterProxy.stackValue(1); | |
| shiftCount = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof anInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| aLarge = createLargeFromSmallInteger(anInteger); | |
| } else { | |
| aLarge = anInteger; | |
| } | |
| if (shiftCount >= 0) { | |
| _return_value = digitLshift(aLarge, shiftCount); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } else { | |
| rShift = 0 - shiftCount; | |
| _return_value = normalize(digitRshiftlookfirst(aLarge, rShift, BYTESIZEOF(aLarge))); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| } | |
| function primDigitAdd() { | |
| var firstLarge; | |
| var firstInteger; | |
| var secondLarge; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitAddLargewith(firstLarge, secondLarge); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| function primDigitAddWith() { | |
| var firstLarge; | |
| var secondLarge; | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitAddLargewith(firstLarge, secondLarge); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| /* Bit logic here is only implemented for positive integers or Zero; if rec | |
| or arg is negative, it fails. */ | |
| function primDigitBitAnd() { | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = digitBitLogicwithopIndex(firstInteger, secondInteger, andOpIndex); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| /* Bit logic here is only implemented for positive integers or Zero; if any arg is negative, it fails. */ | |
| function primDigitBitLogicWithOp() { | |
| var firstInteger; | |
| var secondInteger; | |
| var opIndex; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| firstInteger = interpreterProxy.stackValue(2); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| secondInteger = interpreterProxy.stackValue(1); | |
| opIndex = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = digitBitLogicwithopIndex(firstInteger, secondInteger, opIndex); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(4, _return_value); | |
| return null; | |
| } | |
| /* Bit logic here is only implemented for positive integers or Zero; if rec | |
| or arg is negative, it fails. */ | |
| function primDigitBitOr() { | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = digitBitLogicwithopIndex(firstInteger, secondInteger, orOpIndex); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| function primDigitBitShift() { | |
| var aLarge; | |
| var rShift; | |
| var anInteger; | |
| var shiftCount; | |
| var _return_value; | |
| shiftCount = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| anInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof anInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| aLarge = createLargeFromSmallInteger(anInteger); | |
| } else { | |
| aLarge = anInteger; | |
| } | |
| if (shiftCount >= 0) { | |
| _return_value = digitLshift(aLarge, shiftCount); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| rShift = 0 - shiftCount; | |
| _return_value = normalize(digitRshiftlookfirst(aLarge, rShift, BYTESIZEOF(aLarge))); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| } | |
| function primDigitBitShiftMagnitude() { | |
| var aLarge; | |
| var rShift; | |
| var anInteger; | |
| var shiftCount; | |
| var _return_value; | |
| shiftCount = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| anInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof anInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| aLarge = createLargeFromSmallInteger(anInteger); | |
| } else { | |
| aLarge = anInteger; | |
| } | |
| if (shiftCount >= 0) { | |
| _return_value = digitLshift(aLarge, shiftCount); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| rShift = 0 - shiftCount; | |
| _return_value = normalize(digitRshiftlookfirst(aLarge, rShift, BYTESIZEOF(aLarge))); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| } | |
| /* Bit logic here is only implemented for positive integers or Zero; if rec | |
| or arg is negative, it fails. */ | |
| function primDigitBitXor() { | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = digitBitLogicwithopIndex(firstInteger, secondInteger, xorOpIndex); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| function primDigitCompare() { | |
| var firstVal; | |
| var firstInteger; | |
| var secondVal; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* first */ | |
| if (typeof secondInteger === "number") { | |
| /* second */ | |
| if (((firstVal = firstInteger)) > ((secondVal = secondInteger))) { | |
| _return_value = 1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| if (firstVal < secondVal) { | |
| _return_value = -1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| _return_value = 0; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| } | |
| } else { | |
| /* SECOND */ | |
| _return_value = -1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| } else { | |
| /* FIRST */ | |
| if (typeof secondInteger === "number") { | |
| /* second */ | |
| _return_value = 1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } else { | |
| /* SECOND */ | |
| _return_value = digitCompareLargewith(firstInteger, secondInteger); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| } | |
| } | |
| function primDigitCompareWith() { | |
| var firstVal; | |
| var secondVal; | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* first */ | |
| if (typeof secondInteger === "number") { | |
| /* second */ | |
| if (((firstVal = firstInteger)) > ((secondVal = secondInteger))) { | |
| _return_value = 1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } else { | |
| if (firstVal < secondVal) { | |
| _return_value = -1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } else { | |
| _return_value = 0; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| } | |
| } else { | |
| /* SECOND */ | |
| _return_value = -1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| } else { | |
| /* FIRST */ | |
| if (typeof secondInteger === "number") { | |
| /* second */ | |
| _return_value = 1; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } else { | |
| /* SECOND */ | |
| _return_value = digitCompareLargewith(firstInteger, secondInteger); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| } | |
| } | |
| /* Answer the result of dividing firstInteger by secondInteger. | |
| Fail if parameters are not integers, not normalized or secondInteger is | |
| zero. */ | |
| function primDigitDivNegative() { | |
| var firstAsLargeInteger; | |
| var firstInteger; | |
| var secondAsLargeInteger; | |
| var secondInteger; | |
| var neg; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| secondInteger = interpreterProxy.stackValue(1); | |
| neg = interpreterProxy.booleanValueOf(interpreterProxy.stackValue(0)); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| firstInteger = interpreterProxy.stackValue(2); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (!isNormalized(firstInteger)) { | |
| // missing DebugCode; | |
| interpreterProxy.primitiveFail(); | |
| return null; | |
| } | |
| if (!isNormalized(secondInteger)) { | |
| // missing DebugCode; | |
| interpreterProxy.primitiveFail(); | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert to LargeInteger */ | |
| firstAsLargeInteger = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstAsLargeInteger = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* check for zerodivide and convert to LargeInteger */ | |
| if (secondInteger === 0) { | |
| interpreterProxy.primitiveFail(); | |
| return null; | |
| } | |
| secondAsLargeInteger = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondAsLargeInteger = secondInteger; | |
| } | |
| _return_value = digitDivLargewithnegative(firstAsLargeInteger, secondAsLargeInteger, neg); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| /* Answer the result of dividing firstInteger by secondInteger. | |
| Fail if parameters are not integers or secondInteger is zero. */ | |
| function primDigitDivWithNegative() { | |
| var firstAsLargeInteger; | |
| var secondAsLargeInteger; | |
| var firstInteger; | |
| var secondInteger; | |
| var neg; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| firstInteger = interpreterProxy.stackValue(2); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| secondInteger = interpreterProxy.stackValue(1); | |
| neg = interpreterProxy.booleanValueOf(interpreterProxy.stackValue(0)); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert to LargeInteger */ | |
| firstAsLargeInteger = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstAsLargeInteger = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* check for zerodivide and convert to LargeInteger */ | |
| if (secondInteger === 0) { | |
| interpreterProxy.primitiveFail(); | |
| return null; | |
| } | |
| secondAsLargeInteger = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondAsLargeInteger = secondInteger; | |
| } | |
| _return_value = digitDivLargewithnegative(firstAsLargeInteger, secondAsLargeInteger, neg); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(4, _return_value); | |
| return null; | |
| } | |
| function primDigitMultiplyNegative() { | |
| var firstLarge; | |
| var firstInteger; | |
| var secondLarge; | |
| var secondInteger; | |
| var neg; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| secondInteger = interpreterProxy.stackValue(1); | |
| neg = interpreterProxy.booleanValueOf(interpreterProxy.stackValue(0)); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| firstInteger = interpreterProxy.stackValue(2); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitMultiplyLargewithnegative(firstLarge, secondLarge, neg); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| function primDigitMultiplyWithNegative() { | |
| var firstLarge; | |
| var secondLarge; | |
| var firstInteger; | |
| var secondInteger; | |
| var neg; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| firstInteger = interpreterProxy.stackValue(2); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| secondInteger = interpreterProxy.stackValue(1); | |
| neg = interpreterProxy.booleanValueOf(interpreterProxy.stackValue(0)); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitMultiplyLargewithnegative(firstLarge, secondLarge, neg); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(4, _return_value); | |
| return null; | |
| } | |
| function primDigitSubtract() { | |
| var firstLarge; | |
| var firstInteger; | |
| var secondLarge; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitSubLargewith(firstLarge, secondLarge); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| function primDigitSubtractWith() { | |
| var firstLarge; | |
| var secondLarge; | |
| var firstInteger; | |
| var secondInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| firstInteger = interpreterProxy.stackValue(1); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| secondInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondInteger); | |
| ; | |
| } else { | |
| secondLarge = secondInteger; | |
| } | |
| _return_value = digitSubLargewith(firstLarge, secondLarge); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(3, _return_value); | |
| return null; | |
| } | |
| /* If calling this primitive fails, then C module does not exist. */ | |
| function primGetModuleName() { | |
| var strPtr; | |
| var strLen; | |
| var i; | |
| var strOop; | |
| // missing DebugCode; | |
| strLen = getModuleName().length; | |
| strOop = interpreterProxy.instantiateClassindexableSize(interpreterProxy.classString(), strLen); | |
| strPtr = strOop.bytes; | |
| for (i = 0; i <= (strLen - 1); i++) { | |
| strPtr[i] = getModuleName()[i]; | |
| } | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(1, strOop); | |
| return null; | |
| } | |
| function primMontgomeryTimesModulo() { | |
| var firstLarge; | |
| var secondLarge; | |
| var firstInteger; | |
| var thirdLarge; | |
| var secondOperandInteger; | |
| var thirdModuloInteger; | |
| var smallInverseInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(2))); | |
| secondOperandInteger = interpreterProxy.stackValue(2); | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(1))); | |
| thirdModuloInteger = interpreterProxy.stackValue(1); | |
| smallInverseInteger = interpreterProxy.stackIntegerValue(0); | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(3))); | |
| firstInteger = interpreterProxy.stackValue(3); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof firstInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| firstLarge = createLargeFromSmallInteger(firstInteger); | |
| ; | |
| } else { | |
| firstLarge = firstInteger; | |
| } | |
| if (typeof secondOperandInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| secondLarge = createLargeFromSmallInteger(secondOperandInteger); | |
| ; | |
| } else { | |
| secondLarge = secondOperandInteger; | |
| } | |
| if (typeof thirdModuloInteger === "number") { | |
| /* convert it to a not normalized LargeInteger */ | |
| thirdLarge = createLargeFromSmallInteger(thirdModuloInteger); | |
| ; | |
| } else { | |
| thirdLarge = thirdModuloInteger; | |
| } | |
| _return_value = digitMontgomerytimesmodulomInvModB(firstLarge, secondLarge, thirdLarge, smallInverseInteger); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(4, _return_value); | |
| return null; | |
| } | |
| /* Parameter specification #(Integer) doesn't convert! */ | |
| function primNormalize() { | |
| var anInteger; | |
| var _return_value; | |
| interpreterProxy.success(interpreterProxy.isKindOfInteger(interpreterProxy.stackValue(0))); | |
| anInteger = interpreterProxy.stackValue(0); | |
| // missing DebugCode; | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| if (typeof anInteger === "number") { | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, anInteger); | |
| return null; | |
| } | |
| _return_value = normalize(anInteger); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(2, _return_value); | |
| return null; | |
| } | |
| function primNormalizeNegative() { | |
| var rcvr; | |
| var _return_value; | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.stackValue(0).sqClass === interpreterProxy.classLargeNegativeInteger()); | |
| rcvr = interpreterProxy.stackValue(0); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = normalizeNegative(rcvr); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(1, _return_value); | |
| return null; | |
| } | |
| function primNormalizePositive() { | |
| var rcvr; | |
| var _return_value; | |
| // missing DebugCode; | |
| interpreterProxy.success(interpreterProxy.stackValue(0).sqClass === interpreterProxy.classLargePositiveInteger()); | |
| rcvr = interpreterProxy.stackValue(0); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| _return_value = normalizePositive(rcvr); | |
| if (interpreterProxy.failed()) { | |
| return null; | |
| } | |
| interpreterProxy.popthenPush(1, _return_value); | |
| return null; | |
| } | |
| /* Note: This is coded so that is can be run from Squeak. */ | |
| function setInterpreter(anInterpreter) { | |
| var ok; | |
| interpreterProxy = anInterpreter; | |
| ok = interpreterProxy.majorVersion() == VM_PROXY_MAJOR; | |
| if (ok === false) { | |
| return false; | |
| } | |
| ok = interpreterProxy.minorVersion() >= VM_PROXY_MINOR; | |
| return ok; | |
| } | |
| /* Argument bytesOop must not be aSmallInteger! */ | |
| function unsafeByteOfat(bytesOop, ix) { | |
| var pointer; | |
| return ((pointer = bytesOop.bytes))[ix - 1]; | |
| } | |
| function registerPlugin() { | |
| if (typeof Squeak === "object" && Squeak.registerExternalModule) { | |
| Squeak.registerExternalModule("LargeIntegers", { | |
| primDigitAddWith: primDigitAddWith, | |
| primDigitBitShiftMagnitude: primDigitBitShiftMagnitude, | |
| primGetModuleName: primGetModuleName, | |
| primDigitBitLogicWithOp: primDigitBitLogicWithOp, | |
| primCheckIfCModuleExists: primCheckIfCModuleExists, | |
| primDigitCompare: primDigitCompare, | |
| primDigitMultiplyNegative: primDigitMultiplyNegative, | |
| primDigitBitShift: primDigitBitShift, | |
| primNormalizePositive: primNormalizePositive, | |
| primDigitSubtractWith: primDigitSubtractWith, | |
| _primDigitBitShift: _primDigitBitShift, | |
| primDigitMultiplyWithNegative: primDigitMultiplyWithNegative, | |
| primDigitSubtract: primDigitSubtract, | |
| primDigitDivNegative: primDigitDivNegative, | |
| primNormalizeNegative: primNormalizeNegative, | |
| primDigitBitOr: primDigitBitOr, | |
| primMontgomeryTimesModulo: primMontgomeryTimesModulo, | |
| primDigitBitAnd: primDigitBitAnd, | |
| primDigitDivWithNegative: primDigitDivWithNegative, | |
| setInterpreter: setInterpreter, | |
| primNormalize: primNormalize, | |
| primDigitBitXor: primDigitBitXor, | |
| primDigitCompareWith: primDigitCompareWith, | |
| primDigitAdd: primDigitAdd, | |
| getModuleName: getModuleName, | |
| primAsLargeInteger: primAsLargeInteger, | |
| primAnyBitFromTo: primAnyBitFromTo, | |
| }); | |
| } else self.setTimeout(registerPlugin, 100); | |
| } | |
| registerPlugin(); | |
| })(); // Register module/plugin | |