[Vm-dev] VM Maker: VMMaker-dtl.379.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Mar 28 01:58:05 UTC 2016


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.379.mcz

==================== Summary ====================

Name: VMMaker-dtl.379
Author: dtl
Time: 27 March 2016, 9:51:08.329 pm
UUID: 08564677-5e9d-48d5-a63c-b53bd85489f3
Ancestors: VMMaker-dtl.378

VMMaker 4.15.5
Nicolas Cellier's LargeIntegersPlugin improvements from oscog branch.

=============== Diff against VMMaker-dtl.378 ===============

Item was added:
+ ----- Method: LargeIntegersPlugin>>anyBitOfLargeInt:from:to: (in category 'util') -----
+ anyBitOfLargeInt: aBytesOop from: start to: stopArg 
+ 	"Argument has to be aBytesOop!!"
+ 	"Tests for any magnitude bits in the interval from start to stopArg."
+ 	| magnitude rightShift leftShift stop firstByteIx lastByteIx |
+ 	self
+ 		debugCode: [self msg: 'anyBitOfLargeInt: aBytesOop from: start to: stopArg'].
+ 	start < 1 | (stopArg < 1)
+ 		ifTrue: [^ interpreterProxy primitiveFail].
+ 	magnitude := aBytesOop.
+ 	stop := stopArg
+ 				min: (self highBitOfLargeInt: magnitude).
+ 	start > stop
+ 		ifTrue: [^ false].
+ 	firstByteIx := start - 1 // 8 + 1.
+ 	lastByteIx := stop - 1 // 8 + 1.
+ 	rightShift := (start - 1 \\ 8).
+ 	leftShift := 7 - (stop - 1 \\ 8).
+ 	firstByteIx = lastByteIx
+ 		ifTrue: [| digit mask | 
+ 			mask := (255 << rightShift) bitAnd: (255 >> leftShift).
+ 			digit := self digitOfLargeInt: magnitude at: firstByteIx.
+ 			^ (digit bitAnd: mask)
+ 				~= 0].
+ 	((self digitOfLargeInt: magnitude at: firstByteIx)
+ 			>> rightShift)
+ 			~= 0
+ 		ifTrue: [^ true].
+ 	firstByteIx + 1
+ 		to: lastByteIx - 1
+ 		do: [:ix | (self digitOfLargeInt: magnitude at: ix)
+ 					~= 0
+ 				ifTrue: [^ true]].
+ 	(((self digitOfLargeInt: magnitude at: lastByteIx)
+ 			<< leftShift)
+ 			bitAnd: 255)
+ 			~= 0
+ 		ifTrue: [^ true].
+ 	^ false!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cCopyIntVal:toBytes: (in category 'C core util') -----
  cCopyIntVal: val toBytes: bytes 
  	| pByte |
+ 	<var: #pByte type: #'unsigned char *'>
- 	<var: #pByte type: 'unsigned char *  '>
  	pByte := interpreterProxy firstIndexableField: bytes.
  	1 to: (self cDigitLengthOfCSI: val)
  		do: [:ix | pByte at: ix - 1 put: (self cDigitOfCSI: val at: ix)]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitAdd:len:with:len:into: (in category 'C core') -----
  cDigitAdd: pByteShort len: shortLen with: pByteLong len: longLen into: pByteRes 
  	"pByteRes len = longLen; returns over.."
  	| accum limit |
+ 	<returnTypeC: #'unsigned char'>
+ 	<var: #pByteShort type: #'unsigned char *'>
+ 	<var: #pByteLong type: #'unsigned char *'>
+ 	<var: #pByteRes type: #'unsigned char *'>
+ 	<var: #accum type: #'unsigned int'>
- 	<returnTypeC: 'unsigned char'>
- 	<var: #pByteShort type: 'unsigned char * '>
- 	<var: #pByteLong type: 'unsigned char * '>
- 	<var: #pByteRes type: 'unsigned char * '>
- 	<var: #accum type: 'unsigned int'>
  	accum := 0.
  	limit := shortLen - 1.
  	0 to: limit do: 
  		[:i | 
  		accum := (accum >> 8)
  					+ (pByteShort at: i) + (pByteLong at: i).
  		pByteRes at: i put: (accum bitAnd: 255)].
  	limit := longLen - 1.
  	shortLen to: limit do: 
  		[:i | 
  		accum := (accum >> 8)
  					+ (pByteLong at: i).
  		pByteRes at: i put: (accum bitAnd: 255)].
  	^ accum >> 8!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitCompare:with:len: (in category 'C core') -----
  cDigitCompare: pFirst with: pSecond len: len 
  	"Precondition: pFirst len = pSecond len."
  	| secondDigit ix firstDigit |
+ 	<var: #pFirst type: #'unsigned char *'>
+ 	<var: #pSecond type: #'unsigned char *'>
+ 	<var: #firstDigit type: #'unsigned int'>
+ 	<var: #secondDigit type: #'unsigned int'>
- 	<var: #pFirst type: 'unsigned char * '>
- 	<var: #pSecond type: 'unsigned char * '>
- 	<var: #firstDigit type: 'unsigned int'>
- 	<var: #secondDigit type: 'unsigned int'>
  	ix := len - 1.
  	[ix >= 0]
  		whileTrue: 
  			[(secondDigit := pSecond at: ix) ~= (firstDigit := pFirst at: ix)
  				ifTrue: [secondDigit < firstDigit
  						ifTrue: [^ 1]
  						ifFalse: [^ -1]].
  			ix := ix - 1].
  	^ 0!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitCopyFrom:to:len: (in category 'C core util') -----
  cDigitCopyFrom: pFrom to: pTo len: len 
  	| limit |
+ 	<returnTypeC: #'int'>
+ 	<var: #pFrom type: #'unsigned char *'>
+ 	<var: #pTo type: #'unsigned char *'>
- 	<returnTypeC: 'int'>
- 	<var: #pFrom type: 'unsigned char * '>
- 	<var: #pTo type: 'unsigned char * '>
  
  	self cCode: '' inSmalltalk: [
  		(interpreterProxy isKindOf: InterpreterSimulator) ifTrue: [
  			"called from InterpreterSimulator"
  				limit := len - 1.
  				0 to: limit do: [:i |
  					interpreterProxy byteAt: pTo + i
  						put: (interpreterProxy byteAt: pFrom + i)
  				].
  			^ 0
  		].
  	].	
  	limit := len - 1.
  	0 to: limit do: [:i | pTo at: i put: (pFrom at: i)].
  	^ 0
  !

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitDiv:len:rem:len:quo:len: (in category 'C core') -----
  cDigitDiv: pDiv len: divLen rem: pRem len: remLen quo: pQuo len: quoLen 
  	| dl ql dh dnh j t hi lo r3 l a cond q r1r2 mul b |
+ 	<var: #pDiv type: #'unsigned char *'>
+ 	<var: #pRem type: #'unsigned char *'>
+ 	<var: #pQuo type: #'unsigned char *'>
+ 	<var: #dh type: #'unsigned int'>
+ 	<var: #dnh type: #'unsigned int'>
+ 	<var: #r3 type: #'unsigned int'>
+ 	<var: #q type: #'unsigned int'>
+ 	<var: #a type: #'unsigned int'>
+ 	<var: #b type: #'unsigned int'>
+ 	<var: #t type: #'unsigned int'>
+ 	<var: #mul type: #'unsigned int'>
+ 	<var: #hi type: #'unsigned int'>
+ 	<var: #lo type: #'unsigned int'>
+ 	<var: #r1r2 type: #'unsigned int'>
- 	<var: #pDiv type: 'unsigned char * '>
- 	<var: #pRem type: 'unsigned char * '>
- 	<var: #pQuo type: 'unsigned char * '>
- 	<var: #dh type: 'unsigned int'>
- 	<var: #dnh type: 'unsigned int'>
- 	<var: #r3 type: 'unsigned int'>
- 	<var: #q type: 'unsigned int'>
- 	<var: #a type: 'unsigned int'>
- 	<var: #b type: 'unsigned int'>
- 	<var: #t type: 'unsigned int'>
- 	<var: #mul type: 'unsigned int'>
- 	<var: #hi type: 'unsigned int'>
- 	<var: #lo type: 'unsigned int'>
- 	<var: #r1r2 type: 'unsigned int'>
  	dl := divLen - 1.
  	"Last actual byte of data (ST ix)"
  	ql := quoLen.
  	dh := pDiv at: dl - 1.
  	dl = 1
  		ifTrue: [dnh := 0]
  		ifFalse: [dnh := pDiv at: dl - 2].
  	1 to: ql do: 
  		[: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."
  		j := remLen + 1 - k.
  		"r1 := rem digitAt: j."
  		(pRem at: j - 1)
  			= dh
  			ifTrue: [q := 16rFF]
  			ifFalse: 
  				["Compute q = (r1,r2)//dh, t = (r1,r2)\\dh."
  				"r2 := (rem digitAt: j - 2)."
  				r1r2 := pRem at: j - 1.
  				r1r2 := (r1r2 << 8) + (pRem at: j - 2).
  				t := r1r2 \\ dh.
  				q := r1r2 // dh.
  				"Next compute (hi,lo) := q*dnh"
  				mul := q * dnh.
  				hi := mul >> 8.
  				lo := mul bitAnd: 16rFF.
  				"Correct overestimate of q.                
  				Max of 2 iterations through loop -- see Knuth vol. 2"
  				j < 3
  					ifTrue: [r3 := 0]
  					ifFalse: [r3 := pRem at: j - 3].
  				
  				[(t < hi
  					or: [t = hi and: [r3 < lo]])
  					ifTrue: 
  						["i.e. (t,r3) < (hi,lo)"
  						q := q - 1.
+ 						hi = 0 "since hi is unsigned we must have this guard"
+ 							ifTrue: [cond := false]
- 						lo < dnh
- 							ifTrue: 
- 								[hi := hi - 1.
- 								lo := lo + 16r100 - dnh]
  							ifFalse:
+ 								[lo < dnh
+ 									ifTrue: 
+ 										[hi := hi - 1.
+ 										lo := lo + 16r100 - dnh]
+ 									ifFalse:
+ 										[lo := lo - dnh].
+ 								cond := hi >= dh]]
- 								[lo := lo - dnh].
- 						cond := hi >= dh]
  					ifFalse: [cond := false].
  				cond]
  					whileTrue: [hi := hi - dh]].
  		"Subtract q*div from rem"
  		l := j - dl.
  		a := 0.
  		1 to: divLen do: 
  			[:i | 
  			hi := (pDiv at: i - 1) * (q >> 8).
  			lo := (pDiv at: i - 1) * (q bitAnd: 16rFF).
  			b := (pRem at: l - 1) - a - (lo bitAnd: 16rFF).
  			pRem at: l - 1 put: (b bitAnd: 16rFF).
  			"BEWARE: signed shift is implementation defined in C..."
  			b := b signedBitShift: -8.
  				"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)."
  			a := hi + (lo >> 8) - b.
  			l := l + 1].
  		a > 0
  			ifTrue: 
  				["Add div back into rem, decrease q by 1"
  				q := q - 1.
  				l := j - dl.
  				a := 0.
  				1 to: divLen do: 
  					[:i | 
  					a := (a >> 8)
  								+ (pRem at: l - 1) + (pDiv at: i - 1).
  					pRem at: l - 1 put: (a bitAnd: 16rFF).
  					l := l + 1]].
  		pQuo at: quoLen - k put: q].
  	^0!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitHighBit:len: (in category 'C core util') -----
  cDigitHighBit: pByte len: len 
  	"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."
  	| realLength lastDigit |
+ 	<var: #pByte type: #'unsigned char *'>
+ 	<var: #lastDigit type: #'unsigned int'>
- 	<var: #pByte type: 'unsigned char *  '>
- 	<var: #lastDigit type: 'unsigned int'>
  	realLength := len.
  	[(lastDigit := pByte at: realLength - 1) = 0]
  		whileTrue: [(realLength := realLength - 1) = 0 ifTrue: [^ 0]].
  	^  (self cHighBit: lastDigit) + (8 * (realLength - 1))!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitLengthOfCSI: (in category 'C core util') -----
  cDigitLengthOfCSI: csi 
+ 	"Answer the number of bytes required to represent the value of a CSmallInteger."
+ 	csi >= 0 ifTrue:
+ 		[csi < 256 ifTrue:
+ 			[^1].
+ 		 csi < 65536 ifTrue:
+ 			[^2].
+ 		 csi < 16777216 ifTrue:
+ 			[^3].
+ 		 self bytesPerWord = 4
+ 			ifTrue:
+ 				[^4]
+ 			ifFalse:
+ 				[csi < 4294967296 ifTrue:
+ 					[^4].
+ 				 csi < 1099511627776 ifTrue:
+ 					[^5].
+ 				 csi < 281474976710656 ifTrue:
+ 					[^6].
+ 				 csi < 72057594037927936 ifTrue:
+ 					[^7].
+ 				 ^8]].
+ 	csi > -256 ifTrue:
+ 		[^1].
+ 	csi > -65536 ifTrue:
+ 		[^2].
+ 	csi > -16777216 ifTrue:
+ 		[^3].
+ 	self bytesPerWord = 4
+ 		ifTrue:
+ 			[^4]
+ 		ifFalse:
+ 			[csi > -4294967296 ifTrue:
+ 				[^4].
+ 			 csi > -1099511627776 ifTrue:
+ 				[^5].
+ 			 csi > -281474976710656 ifTrue:
+ 				[^6].
+ 			 csi > -72057594037927936 ifTrue:
+ 				[^7].
+ 			^8]!
- 	"Answer the number of indexable fields of a CSmallInteger. This value is 
- 	   the same as the largest legal subscript."
- 	(csi < 256 and: [csi > -256])
- 		ifTrue: [^ 1].
- 	(csi < 65536 and: [csi > -65536])
- 		ifTrue: [^ 2].
- 	(csi < 16777216 and: [csi > -16777216])
- 		ifTrue: [^ 3].
- 	^ 4!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitLshift:from:len:to:len: (in category 'C core') -----
  cDigitLshift: shiftCount from: pFrom len: lenFrom to: pTo len: lenTo 
  	"C indexed!!"
  	| digitShift bitShift carry limit digit rshift |
+ 	<var: #pTo type: #'unsigned char *'>
+ 	<var: #pFrom type: #'unsigned char *'>
+ 	<var: #carry type: #'unsigned int'>
+ 	<var: #digit type: #'unsigned int'>
- 	<var: #pTo type: 'unsigned char * '>
- 	<var: #pFrom type: 'unsigned char * '>
- 	<var: #carry type: 'unsigned int'>
- 	<var: #digit type: 'unsigned int'>
  	digitShift := shiftCount // 8.
  	bitShift := shiftCount \\ 8.
  	
  	limit := digitShift - 1.
  	0 to: limit do: [:i | pTo at: i put: 0].
  	
  	bitShift = 0 ifTrue: ["Fast version for digit-aligned shifts"
  		"C indexed!!"
  		^ self
  			cDigitReplace: pTo
  			from: digitShift
  			to: lenTo - 1
  			with: pFrom
  			startingAt: 0].
  		
  	"This implementation use at most 15 bits of carry.
  	bitAnd: 16rFF is only for simulator, useless in C"
  	rshift := 8 - bitShift.
  	carry := 0.
  	limit := lenFrom - 1.
  	0 to: limit do: 
  		[:i | 
  		digit := pFrom at: i.
  		pTo at: i + digitShift put: ((carry bitOr: digit << bitShift) bitAnd: 16rFF).
  		carry := digit >> rshift].
  	carry = 0 ifFalse: [pTo at: lenTo - 1 put: carry].
  	^0
  !

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitMontgomery:len:times:len:modulo:len:mInvModB:into: (in category 'C core') -----
  cDigitMontgomery: pBytesFirst
  				len: firstLen
  				times: pBytesSecond
  				len: secondLen
  				modulo: pBytesThird
  				len: thirdLen
  				mInvModB: mInv
  				into: pBytesRes
  				
  	| u limit1 limit2 limit3 accum lastByte |
+ 	<var: #pBytesFirst type: #'unsigned char *'>
+ 	<var: #pBytesSecond type: #'unsigned char *'>
+ 	<var: #pBytesThird type: #'unsigned char *'>
+ 	<var: #pBytesRes type: #'unsigned char *'>
+ 	<var: #accum type: #'unsigned int'>
+ 	<var: #u type: #'unsigned char'>
+ 	<var: #lastByte type: #'unsigned char'>
- 	<var: #pBytesFirst type: 'unsigned char * '>
- 	<var: #pBytesSecond type: 'unsigned char * '>
- 	<var: #pBytesThird type: 'unsigned char * '>
- 	<var: #pBytesRes type: 'unsigned char * '>
- 	<var: #accum type: 'usqInt '>
- 	<var: #u type: 'unsigned char  '>
- 	<var: #lastByte type: 'unsigned char  '>
  	limit1 := firstLen - 1.
  	limit2 := secondLen - 1.
  	limit3 := thirdLen - 1.
  	lastByte := 0.
  	0 to: limit1 do: 
  		[:i | 
  		accum := (pBytesRes at: 0) + ((pBytesFirst at: i)*(pBytesSecond at: 0)).
  		u := accum * mInv bitAnd: 255.
  		accum :=  accum + (u * (pBytesThird at: 0)).
  		1 to: limit2 do: [:k |
  			accum := (accum >> 8) + (pBytesRes at: k) + ((pBytesFirst at: i)*(pBytesSecond at: k)) + (u * (pBytesThird at: k)).
  			pBytesRes at: k-1 put: (accum bitAnd: 255)].
  		secondLen to: limit3 do: [:k |
  			accum := (accum >> 8) + (pBytesRes at: k) + (u * (pBytesThird at: k)).
  			pBytesRes at: k-1 put: (accum bitAnd: 255)].
  		accum := (accum >> 8) + lastByte.
  		pBytesRes at: limit3 put: (accum bitAnd: 255).
  		lastByte := accum >> 8].
  	firstLen to: limit3 do: 
  		[:i | 
  		accum := (pBytesRes at: 0).
  		u := accum * mInv bitAnd: 255.
  		accum := accum + (u * (pBytesThird at: 0)).
  		1 to: limit3 do: [:k |
  			accum := (accum >> 8) + (pBytesRes at: k) + (u * (pBytesThird at: k)).
  			pBytesRes at: k-1 put: (accum bitAnd: 255)].
  		accum := (accum >> 8) + lastByte.
  		pBytesRes at: limit3 put: (accum bitAnd: 255).
  		lastByte := accum >> 8].
  	(lastByte = 0 and: [(self cDigitCompare: pBytesThird with: pBytesRes len: thirdLen) = 1]) ifFalse: [
  		"self cDigitSub: pBytesThird len: thirdLen with: pBytesRes len: thirdLen into: pBytesRes"
  		accum := 0.
  		0 to: limit3 do: 
  			[:i | 
  			accum := accum + (pBytesRes at: i) - (pBytesThird at: i).
+ 			pBytesRes at: i put: (self cCode: [accum] inSmalltalk: [accum bitAnd: 255]).
- 			pBytesRes at: i put: (accum bitAnd: 255).
  			accum := accum signedBitShift: -8]].!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitMultiply:len:with:len:into: (in category 'C core') -----
  cDigitMultiply: pByteShort len: shortLen with: pByteLong len: longLen into: pByteRes 
  	| limitLong digit k carry limitShort ab |
+ 	<returnTypeC: #'unsigned char'>
+ 	<var: #pByteShort type: #'unsigned char *'>
+ 	<var: #pByteLong type: #'unsigned char *'>
+ 	<var: #pByteRes type: #'unsigned char *'>
+ 	<var: #digit type: #'unsigned int'>
+ 	<var: #carry type: #'unsigned int'>
+ 	<var: #ab type: #'unsigned int'>
- 	<returnTypeC: 'unsigned char'>
- 	<var: #pByteShort type: 'unsigned char * '>
- 	<var: #pByteLong type: 'unsigned char * '>
- 	<var: #pByteRes type: 'unsigned char * '>
- 	<var: #digit type: 'unsigned int'>
- 	<var: #carry type: 'unsigned int'>
- 	<var: #ab type: 'unsigned int'>
  	(shortLen = 1 and: [(pByteShort at: 0)
  			= 0])
  		ifTrue: [^ 0].
  	(longLen = 1 and: [(pByteLong at: 0)
  			= 0])
  		ifTrue: [^ 0].
  	"prod starts out all zero"
  	limitShort := shortLen - 1.
  	limitLong := longLen - 1.
  	0 to: limitShort do: [:i | (digit := pByteShort at: i) ~= 0
  			ifTrue: 
  				[k := i.
  				carry := 0.
  				"Loop invariant: 0<=carry<=0377, k=i+j-1 (ST)"
  				"-> Loop invariant: 0<=carry<=0377, k=i+j (C) (?)"
  				0 to: limitLong do: 
  					[:j | 
  					ab := (pByteLong at: j).
  					ab := ab * digit + carry + (pByteRes at: k).
  					carry := ab >> 8.
  					pByteRes at: k put: (ab bitAnd: 16rFF).
  					k := k + 1].
  				pByteRes at: k put: carry]].
  	^ 0!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitOfCSI:at: (in category 'C core util') -----
  cDigitOfCSI: csi at: ix 
  	"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!!"
+ 	^self
+ 		cCode: [(csi < 0
+ 					ifTrue: [0 - csi]
+ 					ifFalse: [csi]) >> (ix - 1 * 8) bitAnd: 255]
+ 		inSmalltalk: [csi digitAt: ix]!
- 	ix < 1 ifTrue: [interpreterProxy primitiveFail].
- 	ix > 4 ifTrue: [^ 0].
- 	csi < 0
- 		ifTrue: 
- 			[self cCode: ''
- 				inSmalltalk: [csi = -1073741824 ifTrue: ["SmallInteger minVal"
- 						"Can't negate minVal -- treat specially"
- 						^ #(0 0 0 64 ) at: ix]].
- 			^ (0 - csi) >> (ix - 1 * 8)
- 				bitAnd: 255]
- 		ifFalse: [^ csi >> (ix - 1 * 8)
- 				bitAnd: 255]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitOp:short:len:long:len:into: (in category 'C core') -----
  cDigitOp: opIndex short: pByteShort len: shortLen long: pByteLong len: longLen into: pByteRes 
  	"pByteRes len = longLen."
  	| limit |
+ 	<var: #pByteShort type: #'unsigned char *'>
+ 	<var: #pByteLong type: #'unsigned char *'>
+ 	<var: #pByteRes type: #'unsigned char *'>
- 	<var: #pByteShort type: 'unsigned char * '>
- 	<var: #pByteLong type: 'unsigned char * '>
- 	<var: #pByteRes type: 'unsigned char * '>
  	limit := shortLen - 1.
  	opIndex = andOpIndex
  		ifTrue: 
  			[0 to: limit do: [:i | pByteRes at: i put: ((pByteShort at: i)
  						bitAnd: (pByteLong at: i))].
  			limit := longLen - 1.
  			shortLen to: limit do: [:i | pByteRes at: i put: 0].
  			^ 0].
  	opIndex = orOpIndex
  		ifTrue: 
  			[0 to: limit do: [:i | pByteRes at: i put: ((pByteShort at: i)
  						bitOr: (pByteLong at: i))].
  			limit := longLen - 1.
  			shortLen to: limit do: [:i | pByteRes at: i put: (pByteLong at: i)].
  			^ 0].
  	opIndex = xorOpIndex
  		ifTrue: 
  			[0 to: limit do: [:i | pByteRes at: i put: ((pByteShort at: i)
  						bitXor: (pByteLong at: i))].
  			limit := longLen - 1.
  			shortLen to: limit do: [:i | pByteRes at: i put: (pByteLong at: i)].
  			^ 0].
  	^ interpreterProxy primitiveFail!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitReplace:from:to:with:startingAt: (in category 'C core util') -----
  cDigitReplace: pTo from: start to: stop with: pFrom startingAt: repStart 
  	"C indexed!!"
+ 	<returnTypeC: #'int'>
+ 	<var: #pTo type: #'unsigned char *'>
+ 	<var: #pFrom type: #'unsigned char *'>
- 	<returnTypeC: 'int'>
- 	<var: #pTo type: 'unsigned char * '>
- 	<var: #pFrom type: 'unsigned char * '>
  	^ self
  		cDigitCopyFrom: pFrom + repStart
  		to: pTo + start
  		len: stop - start + 1!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitRshift:from:len:to:len: (in category 'C core') -----
  cDigitRshift: shiftCount from: pFrom len: fromLen to: pTo len: toLen 
  	| digit bitShift carry digitShift leftShift limit start |
+ 	<var: #pTo type: #'unsigned char *'>
+ 	<var: #pFrom type: #'unsigned char *'>
+ 	<var: #carry type: #'unsigned int'>
+ 	<var: #digit type: #'unsigned int'>
- 	<var: #pTo type: 'unsigned char * '>
- 	<var: #pFrom type: 'unsigned char * '>
- 	<var: #carry type: 'unsigned int '>
- 	<var: #digit type: 'unsigned int '>
  	digitShift := shiftCount // 8.
  	bitShift := shiftCount \\ 8.
  	bitShift = 0 ifTrue: ["Fast version for byte-aligned shifts"
  		"C indexed!!"
  		^self
  			cDigitReplace: pTo
  			from: 0
  			to: toLen - 1
  			with: pFrom
  			startingAt: digitShift].
  		
  	"This implementation use at most 16 bits of x"
  	leftShift := 8 - bitShift.
  	carry := (pFrom at: digitShift) >> bitShift.
  	start := digitShift + 1.
  	limit := fromLen - 1.
  	start to: limit do: 
  		[:j | 
  		digit := pFrom at: j.
  		pTo at: j - start put: ((carry bitOr: digit << leftShift) bitAnd: 16rFF).
  		carry := digit >> bitShift].
  	carry = 0 ifFalse: [pTo at: toLen - 1 put: carry].
  	^0!

Item was changed:
  ----- Method: LargeIntegersPlugin>>cDigitSub:len:with:len:into: (in category 'C core') -----
  cDigitSub: pByteSmall len: smallLen with: pByteLarge len: largeLen into: pByteRes
  	| z |
+ 	<var: #pByteSmall type: #'unsigned char *'>
+ 	<var: #pByteLarge type: #'unsigned char *'>
+ 	<var: #pByteRes type: #'unsigned char *'>
- 	<var: #pByteSmall type: 'unsigned char * '>
- 	<var: #pByteLarge type: 'unsigned char * '>
- 	<var: #pByteRes type: 'unsigned char * '>
- 	<var: #z type: 'unsigned int'>
  
+ 	z := 0. "Loop invariant is -1<=z<=1"
- 	z := 0. "Loop invariant is -1<=z<=0"
  	0 to: smallLen - 1 do: 
  		[:i | 
  		z := z + (pByteLarge at: i) - (pByteSmall at: i).
+ 		pByteRes at: i put: (self cCode: [z] inSmalltalk: [z bitAnd: 255]).
- 		pByteRes at: i put: (z bitAnd: 16rFF).
  		z := z signedBitShift: -8].
  	smallLen to: largeLen - 1 do: 
  		[:i | 
  		z := z + (pByteLarge at: i) .
+ 		pByteRes at: i put: (self cCode: [z] inSmalltalk: [z bitAnd: 255]).
- 		pByteRes at: i put: (z bitAnd: 16rFF).
  		z := z signedBitShift: -8].
  !

Item was changed:
  ----- Method: LargeIntegersPlugin>>cHighBit: (in category 'C core util') -----
  cHighBit: uint 
  	"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."
  	| shifted bitNo |
+ 	<var: #uint type: #'unsigned int'>
+ 	<var: #shifted type: #'unsigned int'>
- 	<var: #uint type: 'unsigned int'>
- 	<var: #shifted type: 'unsigned int  '>
  	shifted := uint.
  	bitNo := 0.
  	shifted < (1 << 16)
  		ifFalse: [shifted := shifted bitShift: -16.
  			bitNo := bitNo + 16].
  	shifted < (1 << 8)
  		ifFalse: [shifted := shifted bitShift: -8.
  			bitNo := bitNo + 8].
  	shifted < (1 << 4)
  		ifFalse: [shifted := shifted bitShift: -4.
  			bitNo := bitNo + 4].
  	shifted < (1 << 2)
  		ifFalse: [shifted := shifted bitShift: -2.
  			bitNo := bitNo + 2].
  	shifted < (1 << 1)
  		ifFalse: [shifted := shifted bitShift: -1.
  			bitNo := bitNo + 1].
  	"shifted 0 or 1 now"
  	^ bitNo + shifted!

Item was changed:
  ----- Method: LargeIntegersPlugin>>createLargeFromSmallInteger: (in category 'oop util') -----
  createLargeFromSmallInteger: anOop 
  	"anOop has to be a SmallInteger!!"
+ 	| val class size res pByte byte |
+ 	<var: #pByte type: #'unsigned char *'>
- 	| val class size res pByte |
- 	<var: #pByte type: 'unsigned char *  '>
  	val := interpreterProxy integerValueOf: anOop.
  	val < 0
  		ifTrue: [class := interpreterProxy classLargeNegativeInteger]
  		ifFalse: [class := interpreterProxy classLargePositiveInteger].
  	size := self cDigitLengthOfCSI: val.
  	res := interpreterProxy instantiateClass: class indexableSize: size.
  	pByte := interpreterProxy firstIndexableField: res.
+ 	1 to: size do: [:ix |
+ 		byte := self cDigitOfCSI: val at: ix.
+ 		pByte at: ix - 1 put: byte].
+ 	^res!
- 	1 to: size do: [:ix | pByte at: ix - 1 put: (self cDigitOfCSI: val at: ix)].
- 	^ res!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digit:Lshift: (in category 'oop functions') -----
  digit: aBytesOop Lshift: shiftCount 
  	"Attention: this method invalidates all oop's!! Only newBytes is valid at return."
  	"Does not normalize."
  	| newBytes highBit newLen oldLen |
+ 	oldLen := self digitSizeOfLargeInt: aBytesOop.
- 	oldLen := self byteSizeOfBytes: aBytesOop.
  	(highBit := self cDigitHighBit: (interpreterProxy firstIndexableField: aBytesOop)
  				len: oldLen) = 0 ifTrue: [^ 0 asOop: SmallInteger].
  	newLen := highBit + shiftCount + 7 // 8.
  	self remapOop: aBytesOop in: [newBytes := interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: aBytesOop)
  					indexableSize: newLen].
  	self
  		cDigitLshift: shiftCount
  		from: (interpreterProxy firstIndexableField: aBytesOop)
  		len: oldLen
  		to: (interpreterProxy firstIndexableField: newBytes)
  		len: newLen.
  	^ newBytes!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitAddLarge:with: (in category 'oop functions') -----
  digitAddLarge: firstInteger with: secondInteger 
  	"Does not need to normalize!!"
  	| over firstLen secondLen shortInt shortLen longInt longLen sum newSum resClass |
+ 	<var: #over type: #'unsigned char'>
+ 	firstLen := self digitSizeOfLargeInt: firstInteger.
+ 	secondLen := self digitSizeOfLargeInt: secondInteger.
- 	<var: #over type: 'unsigned char  '>
- 	firstLen := self byteSizeOfBytes: firstInteger.
- 	secondLen := self byteSizeOfBytes: secondInteger.
  	resClass := interpreterProxy fetchClassOf: firstInteger.
  	firstLen <= secondLen
  		ifTrue: 
  			[shortInt := firstInteger.
  			shortLen := firstLen.
  			longInt := secondInteger.
  			longLen := secondLen]
  		ifFalse: 
  			[shortInt := secondInteger.
  			shortLen := secondLen.
  			longInt := firstInteger.
  			longLen := firstLen].
  	"	sum := Integer new: len neg: firstInteger negative."
  	self remapOop: #(shortInt longInt ) in: [sum := interpreterProxy instantiateClass: resClass indexableSize: longLen].
  	over := self
  				cDigitAdd: (interpreterProxy firstIndexableField: shortInt)
  				len: shortLen
  				with: (interpreterProxy firstIndexableField: longInt)
  				len: longLen
  				into: (interpreterProxy firstIndexableField: sum).
  	over > 0
  		ifTrue: 
  			["sum := sum growby: 1."
  			self remapOop: sum in: [newSum := interpreterProxy instantiateClass: resClass indexableSize: longLen + 1].
  			self
  				cDigitCopyFrom: (interpreterProxy firstIndexableField: sum)
  				to: (interpreterProxy firstIndexableField: newSum)
  				len: longLen.
  			sum := newSum.
  			"C index!!"
  			(self cCoerce: (interpreterProxy firstIndexableField: sum)
  				to: 'unsigned char *')
  				at: longLen put: over].
  	^ sum!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitBitLogic:with:opIndex: (in category 'oop functions') -----
  digitBitLogic: firstInteger with: secondInteger opIndex: opIx 
  	"Bit logic here is only implemented for positive integers or Zero;
  	if rec or arg is negative, it fails."
  	| firstLarge secondLarge firstLen secondLen shortLen shortLarge longLen longLarge result |
  	(interpreterProxy isIntegerObject: firstInteger)
  		ifTrue: 
  			[(interpreterProxy integerValueOf: firstInteger)
  				< 0 ifTrue: [^ interpreterProxy primitiveFail].
  			"convert it to a not normalized LargeInteger"
  			self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
  		ifFalse: 
  			[(interpreterProxy fetchClassOf: firstInteger)
  				= interpreterProxy classLargeNegativeInteger ifTrue: [^ interpreterProxy primitiveFail].
  			firstLarge := firstInteger].
  	(interpreterProxy isIntegerObject: secondInteger)
  		ifTrue: 
  			[(interpreterProxy integerValueOf: secondInteger)
  				< 0 ifTrue: [^ interpreterProxy primitiveFail].
  			"convert it to a not normalized LargeInteger"
  			self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
  		ifFalse: 
  			[(interpreterProxy fetchClassOf: secondInteger)
  				= interpreterProxy classLargeNegativeInteger ifTrue: [^ interpreterProxy primitiveFail].
  			secondLarge := secondInteger].
+ 	firstLen := self digitSizeOfLargeInt: firstLarge.
+ 	secondLen := self digitSizeOfLargeInt: secondLarge.
- 	firstLen := self byteSizeOfBytes: firstLarge.
- 	secondLen := self byteSizeOfBytes: secondLarge.
  	firstLen < secondLen
  		ifTrue: 
  			[shortLen := firstLen.
  			shortLarge := firstLarge.
  			longLen := secondLen.
  			longLarge := secondLarge]
  		ifFalse: 
  			[shortLen := secondLen.
  			shortLarge := secondLarge.
  			longLen := firstLen.
  			longLarge := firstLarge].
  	self remapOop: #(shortLarge longLarge ) in: [result := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: longLen].
  	self
  		cDigitOp: opIx
  		short: (interpreterProxy firstIndexableField: shortLarge)
  		len: shortLen
  		long: (interpreterProxy firstIndexableField: longLarge)
  		len: longLen
  		into: (interpreterProxy firstIndexableField: result).
  	interpreterProxy failed ifTrue: [^ 0].
  	^ self normalizePositive: result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitCompareLarge:with: (in category 'oop functions') -----
  digitCompareLarge: firstInteger with: secondInteger 
  	"Compare the magnitude of firstInteger with that of secondInteger.      
  	Return a code of 1, 0, -1 for firstInteger >, = , < secondInteger"
  	| firstLen secondLen |
+ 	firstLen := self digitSizeOfLargeInt: firstInteger.
+ 	secondLen := self digitSizeOfLargeInt: secondInteger.
- 	firstLen := self byteSizeOfBytes: firstInteger.
- 	secondLen := self byteSizeOfBytes: secondInteger.
  	secondLen ~= firstLen
  		ifTrue: [secondLen > firstLen
  				ifTrue: [^ -1 asOop: SmallInteger]
  				ifFalse: [^ 1 asOop: SmallInteger]].
  	^ (self
  		cDigitCompare: (interpreterProxy firstIndexableField: firstInteger)
  		with: (interpreterProxy firstIndexableField: secondInteger)
  		len: firstLen)
  		asOop: SmallInteger!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitDivLarge:with:negative: (in category 'oop functions') -----
  digitDivLarge: firstInteger with: secondInteger negative: neg 
  	"Does not normalize."
  	"Division by zero has to be checked in caller."
  	| firstLen secondLen resultClass l d div rem quo result |
+ 	firstLen := self digitSizeOfLargeInt: firstInteger.
+ 	secondLen := self digitSizeOfLargeInt: secondInteger.
- 	firstLen := self byteSizeOfBytes: firstInteger.
- 	secondLen := self byteSizeOfBytes: secondInteger.
  	neg
  		ifTrue: [resultClass := interpreterProxy classLargeNegativeInteger]
  		ifFalse: [resultClass := interpreterProxy classLargePositiveInteger].
  	l := firstLen - secondLen + 1.
  	l <= 0
  		ifTrue: 
  			[self remapOop: firstInteger in: [result := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2].
  			result stAt: 1 put: (0 asOop: SmallInteger).
  			result stAt: 2 put: firstInteger.
  			^ result].
  	"set rem and div to copies of firstInteger and secondInteger, respectively. 
  	  However,  
  	 to facilitate use of Knuth's algorithm, multiply rem and div by 2 (that 
  	 is, shift)   
  	 until the high byte of div is >=128"
+ 	d := 8 - (self cHighBit: (self unsafeDigitOf: secondInteger at: secondLen)).
- 	d := 8 - (self cHighBit: (self unsafeByteOf: secondInteger at: secondLen)).
  	self remapOop: firstInteger
  		in: 
  			[div := self digit: secondInteger Lshift: d.
+ 			div := self largeIntOrInt: div growTo: (self digitLength: div)
- 			div := self bytesOrInt: div growTo: (self digitLength: div)
  							+ 1].
  	self remapOop: div
  		in: 
  			[rem := self digit: firstInteger Lshift: d.
  			(self digitLength: rem)
+ 				= firstLen ifTrue: [rem := self largeIntOrInt: rem growTo: firstLen + 1]].
- 				= firstLen ifTrue: [rem := self bytesOrInt: rem growTo: firstLen + 1]].
  	self remapOop: #(div rem ) in: [quo := interpreterProxy instantiateClass: resultClass indexableSize: l].
  	self
  		cDigitDiv: (interpreterProxy firstIndexableField: div)
  		len: (self digitLength: div)
  		rem: (interpreterProxy firstIndexableField: rem)
  		len: (self digitLength: rem)
  		quo: (interpreterProxy firstIndexableField: quo)
  		len: (self digitLength: quo).
  	self remapOop: #(quo ) in: [rem := self
  					digit: rem
  					Rshift: d
  					lookfirst: (self digitLength: div)
  							- 1].
  	"^ Array with: quo with: rem"
  	self remapOop: #(quo rem ) in: [result := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2].
  	result stAt: 1 put: quo.
  	result stAt: 2 put: rem.
  	^ result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitLength: (in category 'util') -----
  digitLength: oop 
  	(interpreterProxy isIntegerObject: oop)
  		ifTrue: [^ self cDigitLengthOfCSI: (interpreterProxy integerValueOf: oop)]
+ 		ifFalse: [^ self digitSizeOfLargeInt: oop]!
- 		ifFalse: [^ self byteSizeOfBytes: oop]!

Item was added:
+ ----- Method: LargeIntegersPlugin>>digitLengthOfNonImmediate: (in category 'util') -----
+ digitLengthOfNonImmediate: oop
+ 	<inline: true>
+ 	^self digitSizeOfLargeInt: oop!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitMontgomery:times:modulo:mInvModB: (in category 'oop functions') -----
  digitMontgomery: firstLarge times: secondLarge modulo: thirdLarge mInvModB: mInv
  
  	| firstLen secondLen thirdLen prod |
+ 	firstLen := self digitSizeOfLargeInt: firstLarge.
+ 	secondLen := self digitSizeOfLargeInt: secondLarge.
+ 	thirdLen := self digitSizeOfLargeInt: thirdLarge.
- 	firstLen := self byteSizeOfBytes: firstLarge.
- 	secondLen := self byteSizeOfBytes: secondLarge.
- 	thirdLen := self byteSizeOfBytes: thirdLarge.
  
  	firstLen <= thirdLen ifFalse: [^interpreterProxy primitiveFail].
  	secondLen <= thirdLen ifFalse: [^interpreterProxy primitiveFail].
  	(mInv >= 0 and: [mInv <= 255]) ifFalse: [^interpreterProxy primitiveFail].
  	self remapOop: #(firstLarge secondLarge thirdLarge) in: [prod := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: thirdLen].
  	self
  				cDigitMontgomery: (interpreterProxy firstIndexableField: firstLarge)
  				len: firstLen
  				times: (interpreterProxy firstIndexableField: secondLarge)
  				len: secondLen
  				modulo: (interpreterProxy firstIndexableField: thirdLarge)
  				len: thirdLen
  				mInvModB: mInv
  				into: (interpreterProxy firstIndexableField: prod).
  	^self normalizePositive: prod!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitMultiplyLarge:with:negative: (in category 'oop functions') -----
  digitMultiplyLarge: firstInteger with: secondInteger negative: neg 
  	"Normalizes."
  	| firstLen secondLen shortInt shortLen longInt longLen prod resultClass |
+ 	firstLen := self digitSizeOfLargeInt: firstInteger.
+ 	secondLen := self digitSizeOfLargeInt: secondInteger.
- 	firstLen := self byteSizeOfBytes: firstInteger.
- 	secondLen := self byteSizeOfBytes: secondInteger.
  	firstLen <= secondLen
  		ifTrue: 
  			[shortInt := firstInteger.
  			shortLen := firstLen.
  			longInt := secondInteger.
  			longLen := secondLen]
  		ifFalse: 
  			[shortInt := secondInteger.
  			shortLen := secondLen.
  			longInt := firstInteger.
  			longLen := firstLen].
  	neg
  		ifTrue: [resultClass := interpreterProxy classLargeNegativeInteger]
  		ifFalse: [resultClass := interpreterProxy classLargePositiveInteger].
  	self remapOop: #(shortInt longInt ) in: [prod := interpreterProxy instantiateClass: resultClass indexableSize: longLen + shortLen].
  	self
  		cDigitMultiply: (interpreterProxy firstIndexableField: shortInt)
  		len: shortLen
  		with: (interpreterProxy firstIndexableField: longInt)
  		len: longLen
  		into: (interpreterProxy firstIndexableField: prod).
  	^ self normalize: prod!

Item was added:
+ ----- Method: LargeIntegersPlugin>>digitOfLargeInt:at: (in category 'util') -----
+ digitOfLargeInt: aBytesOop at: ix 
+ 	"Argument has to be aLargeInteger!!"
+ 	ix > (self digitSizeOfLargeInt: aBytesOop)
+ 		ifTrue: [^ 0]
+ 		ifFalse: [^ self unsafeDigitOf: aBytesOop at: ix]!

Item was added:
+ ----- Method: LargeIntegersPlugin>>digitSizeOfLargeInt: (in category 'util') -----
+ digitSizeOfLargeInt: bytesOop 
+ 	"Precondition: bytesOop is not anInteger and a bytes object."
+ 	^ interpreterProxy slotSizeOf: bytesOop!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitSubLarge:with: (in category 'oop functions') -----
  digitSubLarge: firstInteger with: secondInteger 
  	"Normalizes."
  	| firstLen secondLen larger largerLen smaller smallerLen neg resLen res firstNeg |
  	firstNeg := (interpreterProxy fetchClassOf: firstInteger)
  				= interpreterProxy classLargeNegativeInteger.
+ 	firstLen := self digitSizeOfLargeInt: firstInteger.
+ 	secondLen := self digitSizeOfLargeInt: secondInteger.
- 	firstLen := self byteSizeOfBytes: firstInteger.
- 	secondLen := self byteSizeOfBytes: secondInteger.
  	firstLen = secondLen ifTrue: 
  		[[firstLen > 1
+ 		  and: [(self digitOfLargeInt: firstInteger at: firstLen) = (self digitOfLargeInt: secondInteger at: firstLen)]]
- 		  and: [(self digitOfBytes: firstInteger at: firstLen) = (self digitOfBytes: secondInteger at: firstLen)]]
  			whileTrue: [firstLen := firstLen - 1].
  		secondLen := firstLen].
  	(firstLen < secondLen
  	 or: [firstLen = secondLen
+ 		 and: [(self digitOfLargeInt: firstInteger at: firstLen) < (self digitOfLargeInt: secondInteger at: firstLen)]])
- 		 and: [(self digitOfBytes: firstInteger at: firstLen) < (self digitOfBytes: secondInteger at: firstLen)]])
  		ifTrue: 
  			[larger := secondInteger.
  			largerLen := secondLen.
  			smaller := firstInteger.
  			smallerLen := firstLen.
  			neg := firstNeg == false]
  		ifFalse: 
  			[larger := firstInteger.
  			largerLen := firstLen.
  			smaller := secondInteger.
  			smallerLen := secondLen.
  			neg := firstNeg].
  	resLen := largerLen.
  	self remapOop: #(smaller larger)
  		in: [res := interpreterProxy
  					instantiateClass: (neg
  										ifTrue: [interpreterProxy classLargeNegativeInteger]
  										ifFalse: [interpreterProxy classLargePositiveInteger])
  					indexableSize: resLen].
  	self
  		cDigitSub: (interpreterProxy firstIndexableField: smaller)
  		len: smallerLen
  		with: (interpreterProxy firstIndexableField: larger)
  		len: largerLen
  		into: (interpreterProxy firstIndexableField: res).
  	^neg 
  		ifTrue: [self normalizeNegative: res]
  		ifFalse: [self normalizePositive: res]!

Item was added:
+ ----- Method: LargeIntegersPlugin>>highBitOfLargeInt: (in category 'util') -----
+ highBitOfLargeInt: aBytesOop 
+ 	^ self cDigitHighBit: (interpreterProxy firstIndexableField: aBytesOop)
+ 		len: (self digitSizeOfLargeInt: aBytesOop)!

Item was added:
+ ----- Method: LargeIntegersPlugin>>largeInt:growTo: (in category 'oop util') -----
+ largeInt: aBytesObject growTo: newLen 
+ 	"Attention: this method invalidates all oop's!! Only newBytes is valid at return."
+ 	"Does not normalize."
+ 	| newBytes oldLen copyLen |
+ 	self remapOop: aBytesObject in: [newBytes := interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: aBytesObject)
+ 					indexableSize: newLen].
+ 	oldLen := self digitSizeOfLargeInt: aBytesObject.
+ 	oldLen < newLen
+ 		ifTrue: [copyLen := oldLen]
+ 		ifFalse: [copyLen := newLen].
+ 	self
+ 		cDigitCopyFrom: (interpreterProxy firstIndexableField: aBytesObject)
+ 		to: (interpreterProxy firstIndexableField: newBytes)
+ 		len: copyLen.
+ 	^ newBytes!

Item was added:
+ ----- Method: LargeIntegersPlugin>>largeIntOrInt:growTo: (in category 'oop util') -----
+ largeIntOrInt: oop growTo: len 
+ 	"Attention: this method invalidates all oop's!! Only newBytes is valid at return."
+ 	| newBytes val class |
+ 	(interpreterProxy isIntegerObject: oop)
+ 		ifTrue: 
+ 			[val := interpreterProxy integerValueOf: oop.
+ 			val < 0
+ 				ifTrue: [class := interpreterProxy classLargeNegativeInteger]
+ 				ifFalse: [class := interpreterProxy classLargePositiveInteger].
+ 			newBytes := interpreterProxy instantiateClass: class indexableSize: len.
+ 			self cCopyIntVal: val toBytes: newBytes]
+ 		ifFalse: [newBytes := self largeInt: oop growTo: len].
+ 	^ newBytes!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primAnyBitFrom:to: (in category 'Integer primitives') -----
  primAnyBitFrom: from to: to 
  	| integer large |
  	self debugCode: [self msg: 'primAnyBitFrom: from to: to'].
  	integer := self
  				primitive: 'primAnyBitFromTo'
  				parameters: #(#SmallInteger #SmallInteger )
  				receiver: #Integer.
  	(interpreterProxy isIntegerObject: integer)
  		ifTrue: ["convert it to a not normalized LargeInteger"
  			large := self createLargeFromSmallInteger: integer]
  		ifFalse: [large := integer].
  	^ (self
+ 		anyBitOfLargeInt: large
- 		anyBitOfBytes: large
  		from: from
  		to: to)
  		asOop: Boolean!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigit:bitShift: (in category 'development primitives') -----
  primDigit: anInteger bitShift: shiftCount 
  	| rShift aLarge |
  	self debugCode: [self msg: 'primDigit: anInteger bitShift: shiftCount'].
  	self
  		primitive: '_primDigitBitShift'
  		parameters: #(Integer SmallInteger )
  		receiver: #Oop.
  	(interpreterProxy isIntegerObject: anInteger)
  		ifTrue: ["convert it to a not normalized LargeInteger"
  			aLarge := self createLargeFromSmallInteger: anInteger]
  		ifFalse: [aLarge := anInteger].
  	shiftCount >= 0
  		ifTrue: [^ self digit: aLarge Lshift: shiftCount]
  		ifFalse: 
  			[rShift := 0 - shiftCount.
  			^ self normalize: (self
  					digit: aLarge
  					Rshift: rShift
+ 					lookfirst: (self digitSizeOfLargeInt: aLarge))]!
- 					lookfirst: (self byteSizeOfBytes: aLarge))]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitShift: (in category 'obsolete') -----
  primDigitBitShift: shiftCount 
  	| rShift aLarge anInteger |
  	self debugCode: [self msg: 'primDigitBitShift: shiftCount'].
  	anInteger := self
  				primitive: 'primDigitBitShift'
  				parameters: #(SmallInteger )
  				receiver: #Integer.
  	(interpreterProxy isIntegerObject: anInteger)
  		ifTrue: ["convert it to a not normalized LargeInteger"
  			aLarge := self createLargeFromSmallInteger: anInteger]
  		ifFalse: [aLarge := anInteger].
  	shiftCount >= 0
  		ifTrue: [^ self digit: aLarge Lshift: shiftCount]
  		ifFalse: 
  			[rShift := 0 - shiftCount.
  			^ self normalize: (self
  					digit: aLarge
  					Rshift: rShift
+ 					lookfirst: (self digitSizeOfLargeInt: aLarge))]!
- 					lookfirst: (self byteSizeOfBytes: aLarge))]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primDigitBitShiftMagnitude: (in category 'Integer primitives') -----
  primDigitBitShiftMagnitude: shiftCount 
  	| rShift aLarge anInteger |
  	self debugCode: [self msg: 'primDigitBitShiftMagnitude: shiftCount'].
  	anInteger := self
  				primitive: 'primDigitBitShiftMagnitude'
  				parameters: #(#SmallInteger )
  				receiver: #Integer.
  	(interpreterProxy isIntegerObject: anInteger)
  		ifTrue: ["convert it to a not normalized LargeInteger"
  			aLarge := self createLargeFromSmallInteger: anInteger]
  		ifFalse: [aLarge := anInteger].
  	shiftCount >= 0
  		ifTrue: [^ self digit: aLarge Lshift: shiftCount]
  		ifFalse: 
  			[rShift := 0 - shiftCount.
  			^ self normalize: (self
  					digit: aLarge
  					Rshift: rShift
+ 					lookfirst: (self digitSizeOfLargeInt: aLarge))]!
- 					lookfirst: (self byteSizeOfBytes: aLarge))]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>primGetModuleName (in category 'control & support primitives') -----
  primGetModuleName
  	"If calling this primitive fails, then C module does not exist."
+ 	| strLen strOop |
- 	| strLen strOop strPtr |
- 	<var: #cString type: 'char *'>
- 	<var: #strPtr type: 'char *'>
  	self debugCode: [self msg: 'primGetModuleName'].
  	self
  		primitive: 'primGetModuleName'
  		parameters: #()
  		receiver: #Oop.
  	strLen := self strlen: self getModuleName.
  	strOop := interpreterProxy instantiateClass: interpreterProxy classString indexableSize: strLen.
+ 	self st: (interpreterProxy firstIndexableField: strOop)
+ 		rn: self getModuleName
+ 		cpy: strLen.
+ 	^strOop!
- 	strPtr := interpreterProxy firstIndexableField: strOop.
- 	0 to: strLen - 1 do: [:i | strPtr at: i put: (self getModuleName at: i)].
- 	^ strOop!

Item was added:
+ ----- Method: LargeIntegersPlugin>>primMontgomeryDigitLength (in category 'Integer primitives') -----
+ primMontgomeryDigitLength
+ 	self debugCode: [self msg: 'primMontgomeryDigitLength'].
+ 	self
+ 				primitive: 'primMontgomeryDigitLength'
+ 				parameters: #()
+ 				receiver: #Integer.
+ 	^interpreterProxy integerObjectOf: 8!

Item was added:
+ ----- Method: LargeIntegersPlugin>>unsafeDigitOf:at: (in category 'util') -----
+ unsafeDigitOf: bytesObj at: ix
+ 	"Argument bytesObj must not be aSmallInteger!!"
+ 	<inline: true>
+ 	^(interpreterProxy cCoerce: (interpreterProxy firstIndexableField: bytesObj) to: #'unsigned char *') at: ix - 1!

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.15.5'!
- 	^'4.15.4'!



More information about the Vm-dev mailing list