Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3015.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3015 Author: eem Time: 2 August 2021, 5:43:30.36731 pm UUID: 2f7fd362-d443-4e59-9725-ebc5b7b3fcc1 Ancestors: VMMaker.oscog-eem.3014
Have the CroquetPlugin primitives use the FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag flags. Use the methodReturnFoo: protocol.
=============== Diff against VMMaker.oscog-eem.3014 ===============
Item was changed: ----- Method: B3DAcceleratorPlugin>>stackMatrix: (in category 'primitive support') ----- stackMatrix: index "Load a 4x4 transformation matrix from the interpreter stack. Return a pointer to the matrix data if successful, nil otherwise." | oop | + <inline: #always> + oop := interpreterProxy stackValue: index. + ((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 16]) ifTrue: + [^interpreterProxy firstIndexableField: oop]. + interpreterProxy primitiveFail. - <inline: false> - returnTypeC:'void*' - oop := interpreterProxy stackObjectValue: index. - oop = nil ifTrue:[^nil]. - ((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 16]) - ifTrue:[^interpreterProxy firstIndexableField: oop]. ^nil!
Item was changed: ----- Method: CroquetPlugin>>primitiveARC4Transform (in category 'cryptography') ----- primitiveARC4Transform "Perform an ARC4 transform of input. Arguments: buffer <ByteArray> transformed data startIndex <Integer> start of transform stopIndex <Integer> end of transform m <ByteArray> key stream data x <Integer> key state value y <Integer> key state value Return value: x@y - updated key state value "
+ <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> "Align in case the compiler identifies and generates vector instructions" | y x mOop stopIndex startIndex bufOop bufSize buffer a m b mask ptOop xOop yOop | + <var: 'buffer' type: #'unsigned char *'> + <var: 'm' type: #'unsigned char *'> - <export: true> - <var: 'buffer' type: 'unsigned char *'> - <var: 'm' type: 'unsigned char *'>
interpreterProxy methodArgumentCount = 6 ifFalse:[^interpreterProxy primitiveFail]. "pick up arguments" y := interpreterProxy stackIntegerValue: 0. x := interpreterProxy stackIntegerValue: 1. + mOop := interpreterProxy stackValue: 2. - mOop := interpreterProxy stackObjectValue: 2. stopIndex := interpreterProxy stackIntegerValue: 3. startIndex := interpreterProxy stackIntegerValue: 4. + bufOop := interpreterProxy stackValue: 5. - bufOop := interpreterProxy stackObjectValue: 5. interpreterProxy failed ifTrue:[^nil]. + ((interpreterProxy isBytes: mOop) + and: [(interpreterProxy isBytes: bufOop) + and: [(interpreterProxy byteSizeOf: mOop) = 256 + and: [startIndex > 0 and: [startIndex <= (bufSize := interpreterProxy byteSizeOf: bufOop) + and: [stopIndex >= startIndex and: [stopIndex <= bufSize]]]]]]) ifFalse: + [^interpreterProxy primitiveFail]. - ((interpreterProxy isBytes: mOop) and:[interpreterProxy isBytes: bufOop]) - ifFalse:[^interpreterProxy primitiveFail]. - (interpreterProxy byteSizeOf: mOop) = 256 - ifFalse:[^interpreterProxy primitiveFail]. - bufSize := interpreterProxy byteSizeOf: bufOop. - (startIndex > 0 and:[startIndex <= bufSize]) - ifFalse:[^interpreterProxy primitiveFail]. - (stopIndex >= startIndex and:[stopIndex <= bufSize]) - ifFalse:[^interpreterProxy primitiveFail]. m := interpreterProxy firstIndexableField: mOop. buffer := interpreterProxy firstIndexableField: bufOop. startIndex-1 to: stopIndex-1 do:[:i| x := (x + 1) bitAnd: 255. a := m at: x. y := (y + a) bitAnd: 255. b := m at: y. m at: x put: b. m at: y put: a. mask := m at: ((a + b) bitAnd: 255). buffer at: i put: ((buffer at: i) bitXor: mask). ]. ptOop := interpreterProxy instantiateClass: interpreterProxy classPoint indexableSize: 0. + self cppIf: #SPURVM + ifTrue: + [xOop := interpreterProxy positive32BitIntegerFor: x. + yOop := interpreterProxy positive32BitIntegerFor: y. + (ptOop isNil or: [xOop isNil or: [yOop isNil]]) ifTrue: + [^interpreterProxy primitiveFailFor: PrimErrNoMemory]. + interpreterProxy storePointer: 0 ofObject: ptOop withValue: xOop. + interpreterProxy storePointer: 1 ofObject: ptOop withValue: yOop] + ifFalse: + [interpreterProxy pushRemappableOop: ptOop. + xOop := interpreterProxy positive32BitIntegerFor: x. + interpreterProxy pushRemappableOop: xOop. + yOop := interpreterProxy positive32BitIntegerFor: y. + xOop := interpreterProxy popRemappableOop. + ptOop := interpreterProxy popRemappableOop. + interpreterProxy storePointer: 0 ofObject: ptOop withValue: xOop. + interpreterProxy storePointer: 1 ofObject: ptOop withValue: yOop]. + ^interpreterProxy methodReturnValue: ptOop! - interpreterProxy pushRemappableOop: ptOop. - xOop := interpreterProxy positive32BitIntegerFor: x. - interpreterProxy pushRemappableOop: xOop. - yOop := interpreterProxy positive32BitIntegerFor: y. - xOop := interpreterProxy popRemappableOop. - ptOop := interpreterProxy popRemappableOop. - interpreterProxy storePointer: 0 ofObject: ptOop withValue: xOop. - interpreterProxy storePointer: 1 ofObject: ptOop withValue: yOop. - interpreterProxy pop: interpreterProxy methodArgumentCount + 1. - ^interpreterProxy push: ptOop. - !
Item was changed: ----- Method: CroquetPlugin>>primitiveAdj3 (in category 'transforms') ----- primitiveAdj3 "Computes the adjoint of the Matrix4x4 receiver, placing the results the the Matrix4x4 argument, " + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + | + srcOop src - | - argc - srcOop src dstOop dst + m11 m12 m13 m21 m22 m23 m31 m32 m33 + c11 c12 c13 c21 c22 c23 c31 c32 c33 - m11 m12 m13 m21 m22 m23 m31 m32 m33 - c11 c12 c13 c21 c22 c23 c31 c32 c33 - | - <export: true> - <inline: true> <var: #c11 declareC: 'const int c11 = 0'> <var: #c12 declareC: 'const int c12 = 1'> <var: #c13 declareC: 'const int c13 = 2'> "<var: #c14 declareC: 'const int c14 = 3'>" <var: #c21 declareC: 'const int c21 = 4'> <var: #c22 declareC: 'const int c22 = 5'> <var: #c23 declareC: 'const int c23 = 6'> "<var: #c24 declareC: 'const int c24 = 7'>" <var: #c31 declareC: 'const int c31 = 8'> <var: #c32 declareC: 'const int c32 = 9'> <var: #c33 declareC: 'const int c33 = 10'> "<var: #c34 declareC: 'const int c34 = 11'>" + <var: #m11 type: #double> + <var: #m12 type: #double> + <var: #m13 type: #double> + <var: #m21 type: #double> + <var: #m22 type: #double> + <var: #m23 type: #double> + <var: #m31 type: #double> + <var: #m32 type: #double> + <var: #m33 type: #double> - <var: #src type: 'float *'> - <var: #dst type: 'float *'> - <var: #m11 type: 'double'> - <var: #m12 type: 'double'> - <var: #m13 type: 'double'> - <var: #m21 type: 'double'> - <var: #m22 type: 'double'> - <var: #m23 type: 'double'> - <var: #m31 type: 'double'> - <var: #m32 type: 'double'> - <var: #m33 type: 'double'>
"then we need the following no-op to make Smalltalk shut up about vars not being initted." self cCode: '' inSmalltalk: [ c11 := 0. c12 := 1. c13 := 2. "c14 := 3." c21 := 4. c22 := 5. c23 := 6. "c24 := 7." c31 := 8. c32 := 9. c33 := 10. "c34 := 11." ].
"NOTE: the bottom row of a OpenGL-ordered matrix is always 0 0 0 1, so we don't need consts here for those elements."
+ srcOop := interpreterProxy stackObjectValue: 1. + dstOop := interpreterProxy stackObjectValue: 0. + interpreterProxy failed ifTrue: + [^nil]. + src := self cCoerce: (interpreterProxy firstIndexableField: srcOop) to: #'float *'. + dst := self cCoerce: (interpreterProxy firstIndexableField: dstOop) to: #'float *'. - "do the dance to get our receiver and argument" - argc := interpreterProxy methodArgumentCount. - argc = 1 - ifFalse:[^interpreterProxy primitiveFail].
- "stackArgvObject is something I added to Interpreter, but since it's not in there yet, - this won't compile - use it when it's there. Yes, it would be nice if Smalltalk had #ifdefs..." - self flag: #stackArgv. - " - srcOop := interpreterProxy stackArgvObject: 0. - src := interpreterProxy firstIndexableField: srcOop. - - dstOop := interpreterProxy stackArgvObject: 1. - dst := interpreterProxy firstIndexableField: dstOop. - " - srcOop := interpreterProxy stackObjectValue: argc. - src := interpreterProxy firstIndexableField: srcOop. - - dstOop := interpreterProxy stackObjectValue: (argc - 1). - dst := interpreterProxy firstIndexableField: dstOop. - - "read in the source matrix 3x3, which contains the encoded rotation and scale factors" m11 := src at: c11. m12 := src at: c12. m13 := src at: c13. m21 := src at: c21. m22 := src at: c22. m23 := src at: c23. m31 := src at: c31. m32 := src at: c32. m33 := src at: c33.
"do the actual work"
"compute our cofactors and transpose. adj = transpose of cofactors" dst at: c11 put: ((m22 * m33) - (m23 * m32)) . dst at: c21 put: (0.0 - ((m21 * m33) - (m23 * m31))). dst at: c31 put: ((m21 * m32) - (m22 * m31)).
dst at: c12 put: (0.0 - ((m12 * m33) - (m13 * m32))). dst at: c22 put: ((m11 * m33) - (m13 * m31)). dst at: c32 put: (0.0 - ((m11 * m32) - (m12 * m31))).
dst at: c13 put: ((m12 * m23) - (m13 * m22)). dst at: c23 put: (0.0 - ((m11 * m23) - (m13 * m21))). dst at: c33 put: ((m11 * m22) - (m12 * m21)). + ^interpreterProxy methodReturnValue: dstOop! - interpreterProxy pop: argc + 1 thenPush: dstOop - !
Item was changed: ----- Method: CroquetPlugin>>primitiveDet3 (in category 'transforms') ----- primitiveDet3 "Computes the determinant of the upper 3x3 of a Matrix4x4" + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + | srcOop src m11 m12 m13 m21 m22 m23 m31 m32 m33 | + <var: #m11 type: #double> + <var: #m12 type: #double> + <var: #m13 type: #double> + <var: #m21 type: #double> + <var: #m22 type: #double> + <var: #m23 type: #double> + <var: #m31 type: #double> + <var: #m32 type: #double> + <var: #m33 type: #double> - | argc srcOop src det m11 m12 m13 m21 m22 m23 m31 m32 m33 | - <export: true> - <inline: true> - <var: #src type: 'float *'> - <var: #m11 type: 'double'> - <var: #m12 type: 'double'> - <var: #m13 type: 'double'> - <var: #m21 type: 'double'> - <var: #m22 type: 'double'> - <var: #m23 type: 'double'> - <var: #m31 type: 'double'> - <var: #m32 type: 'double'> - <var: #m33 type: 'double'> - <var: #det type: 'double'>
- argc := interpreterProxy methodArgumentCount. - argc = 0 - ifFalse:[^interpreterProxy primitiveFail]. - - " Load element vars using C version of Matrix4x4 storage, as 0-based, 1-dimensional array: 0 1 2 3 4 5 6 7 8 9 10 11 " + srcOop := interpreterProxy stackObjectValue: 0. + interpreterProxy failed ifTrue: + [^nil]. + src := self cCoerce: (interpreterProxy firstIndexableField: srcOop) to: #'float *'.
- "stackArgvObject is something I added to Interpreter, but since it's not in there yet, - this won't compile - use it when it's there. Yes, it would be nice if Smalltalk had #ifdefs..." - self flag: #stackArgv. - " - srcOop := interpreterProxy stackArgvObject: 0. - src := interpreterProxy firstIndexableField: srcOop. - " - srcOop := interpreterProxy stackObjectValue: argc. - src := interpreterProxy firstIndexableField: srcOop. - - m11 := src at: 0. m12 := src at: 1. m13 := src at: 2. m21 := src at: 4. m22 := src at: 5. m23 := src at: 6. m31 := src at: 8. m32 := src at: 9. m33 := src at: 10.
+ ^interpreterProxy methodReturnFloat: (m11 * ((m22 * m33) - (m23 * m32))) + + (m12 * ((m23 * m31) - (m21 * m33))) + + (m13 * ((m21 * m32) - (m22 * m31))) - - "do the actual work" - det := - ( m11 * ((m22 * m33) - (m23 * m32))) + - (m12 * ((m23 * m31) - (m21 * m33))) + - (m13 * ((m21 * m32) - (m22 * m31))). - - - interpreterProxy pop: argc + 1. - ^interpreterProxy pushFloat: det. !
Item was changed: ----- Method: CroquetPlugin>>primitiveGatherEntropy (in category 'cryptography') ----- primitiveGatherEntropy "Primitive. Gather good random entropy from a system source." - | bufOop bufSize bufPtr okay | <export: true> + | bufOop | + bufOop := interpreterProxy stackValue: 0. + ((interpreterProxy isBytes: bufOop) + and: [self ioGatherEntropy: (interpreterProxy firstIndexableField: bufOop) _: (interpreterProxy byteSizeOf: bufOop)]) ifFalse: + [^interpreterProxy primitiveFail]. + ^interpreterProxy methodReturnBool: true! - <var: 'bufPtr' type: 'void *'> - (interpreterProxy methodArgumentCount = 1) - ifFalse:[^interpreterProxy primitiveFail]. - bufOop := interpreterProxy stackObjectValue: 0. - interpreterProxy failed ifTrue:[^nil]. - (interpreterProxy isBytes: bufOop) - ifFalse:[^interpreterProxy primitiveFail]. - bufSize := interpreterProxy byteSizeOf: bufOop. - bufPtr := interpreterProxy firstIndexableField: bufOop. - okay := self cCode: 'ioGatherEntropy(bufPtr, bufSize)' inSmalltalk:[bufPtr. bufSize. false]. - okay ifFalse:[^interpreterProxy primitiveFail]. - interpreterProxy pop: interpreterProxy methodArgumentCount + 1. - ^interpreterProxy pushBool: true.!
Item was changed: ----- Method: CroquetPlugin>>primitiveInplaceHouseHolderInvert (in category 'transforms') ----- primitiveInplaceHouseHolderInvert "Primitive. Perform an inplace house holder matrix inversion" + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> | rcvr d x sigma beta sum s m | + <var: #rcvr type: #'float *'> - <export: true> - <var: #rcvr declareC:'float *rcvr'> <var: #m declareC:'double m[4][4]'> <var: #x declareC:'double x[4][4] = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} }'> <var: #d declareC:'double d[4][4]'> + <var: #sigma type: #double> + <var: #beta type: #double> + <var: #sum type: #double> + <var: #s type: #double> - <var: #sigma declareC:'double sigma'> - <var: #beta declareC:'double beta'> - <var: #sum declareC:'double sum'> - <var: #s declareC:'double s'>
self cCode:'' inSmalltalk:[ m := CArrayAccessor on: ((1 to: 4) collect:[:i| CArrayAccessor on: (Array new: 4)]). x := CArrayAccessor on: (Array with: (CArrayAccessor on: #(1.0 0.0 0.0 0.0) copy) with: (CArrayAccessor on: #(0.0 1.0 0.0 0.0) copy) with: (CArrayAccessor on: #(0.0 0.0 1.0 0.0) copy) with: (CArrayAccessor on: #(0.0 0.0 0.0 1.0) copy)). d := CArrayAccessor on: ((1 to: 4) collect:[:i| CArrayAccessor on: (Array new: 4)]). ]. rcvr := self stackMatrix: 0. + rcvr ifNil: + [^interpreterProxy primitiveFail]. 0 to: 3 do:[:i| 0 to: 3 do:[:j| (m at: i) at: j put: (rcvr at: i*4+j)]]. 0 to: 3 do:[:j| sigma := 0.0. j to: 3 do:[:i| sigma := sigma + (((m at: i) at: j) * ((m at: i) at: j))]. sigma < 1.0e-10 ifTrue:[^interpreterProxy primitiveFail]. "matrix is singular" (((m at: j) at: j) < 0.0) ifTrue:[ s:= sigma sqrt] ifFalse:[ s:= 0.0 - sigma sqrt]. 0 to: 3 do:[:r| (d at: j) at: r put: s]. beta := 1.0 / ( s * ((m at: j) at: j) - sigma). (m at: j) at: j put: (((m at: j) at: j) - s). "update remaining columns" j+1 to: 3 do:[:k| sum := 0.0. j to: 3 do:[:i| sum := sum + (((m at: i) at: j) * ((m at: i) at: k))]. sum := sum * beta. j to: 3 do:[:i| (m at: i) at: k put: (((m at: i) at: k) + (((m at: i) at: j) * sum))]]. "update vector" 0 to: 3 do:[:r| sum := 0.0. j to: 3 do:[:i| sum := sum + (((x at: i) at: r) * ((m at: i) at: j))]. sum := sum * beta. j to: 3 do:[:i| (x at: i) at: r put:(((x at: i) at: r) + (sum * ((m at: i) at: j)))]. ]. ]. "Now calculate result" 0 to: 3 do:[:r| 3 to: 0 by: -1 do:[:i| i+1 to: 3 do:[:j| (x at: i) at: r put: (((x at: i) at: r) - (((x at: j) at: r) * ((m at: i) at: j))) ]. (x at: i) at: r put: (((x at: i) at: r) / ((d at: i) at: r))]. ]. 0 to: 3 do:[:i| 0 to: 3 do:[:j| rcvr at: i*4+j put: (self cCoerce: ((x at: i) at: j) to:'float')]]. "Return receiver" ^nil!
Item was changed: ----- Method: CroquetPlugin>>primitiveInverseByAdjoint (in category 'transforms') ----- primitiveInverseByAdjoint "Computes the inverse of the Matrix4x4 receiver, using the 'classical adjoint' method, placing the results the the Matrix4x4 argument, " + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> + | + srcOop src - | - srcOop src dstOop dst + det + m11 m12 m13 m21 m22 m23 m31 m32 m33 + c11 c12 c13 c14 c21 c22 c23 c24 c31 c32 c33 c34 + x y z + | - det - m11 m12 m13 m21 m22 m23 m31 m32 m33 - c11 c12 c13 c14 c21 c22 c23 c24 c31 c32 c33 c34 - x y z - argc | - <export: true> - <inline: true> <var: #c11 declareC: 'const int c11 = 0'> <var: #c12 declareC: 'const int c12 = 1'> <var: #c13 declareC: 'const int c13 = 2'> <var: #c14 declareC: 'const int c14 = 3'> <var: #c21 declareC: 'const int c21 = 4'> <var: #c22 declareC: 'const int c22 = 5'> <var: #c23 declareC: 'const int c23 = 6'> <var: #c24 declareC: 'const int c24 = 7'> <var: #c31 declareC: 'const int c31 = 8'> <var: #c32 declareC: 'const int c32 = 9'> <var: #c33 declareC: 'const int c33 = 10'> <var: #c34 declareC: 'const int c34 = 11'> + <var: #m11 type: #double> + <var: #m12 type: #double> + <var: #m13 type: #double> + <var: #m21 type: #double> + <var: #m22 type: #double> + <var: #m23 type: #double> + <var: #m31 type: #double> + <var: #m32 type: #double> + <var: #m33 type: #double> + <var: #x type:#double> + <var: #y type:#double> + <var: #z type:#double> + <var: #det type:#double> - <var: #src type: 'float *'> - <var: #dst type: 'float *'> - <var: #m11 type: 'double'> - <var: #m12 type: 'double'> - <var: #m13 type: 'double'> - <var: #m21 type: 'double'> - <var: #m22 type: 'double'> - <var: #m23 type: 'double'> - <var: #m31 type: 'double'> - <var: #m32 type: 'double'> - <var: #m33 type: 'double'> - <var: #x type: 'double'> - <var: #y type: 'double'> - <var: #z type: 'double'> - <var: #det type: 'double'>
"then we need the following no-op to make Smalltalk shut up about vars not being initted." self cCode: '' inSmalltalk: [ c11 := 0. c12 := 1. c13 := 2. c14 := 3. c21 := 4. c22 := 5. c23 := 6. c24 := 7. c31 := 8. c32 := 9. c33 := 10. c34 := 11. ].
"NOTE: the bottom row of a OpenGL-ordered matrix is always 0 0 0 1, so we don't need consts here for those elements."
"do the dance to get our receiver and argument" + srcOop := interpreterProxy stackValue: 1. + dstOop := interpreterProxy stackValue: 0. + interpreterProxy failed ifTrue: + [^nil]. + src := self cCoerce: (interpreterProxy firstIndexableField: srcOop) to: #'float *'. + dst := self cCoerce: (interpreterProxy firstIndexableField: dstOop) to: #'float *'. - argc := interpreterProxy methodArgumentCount. - argc = 1 - ifFalse:[^interpreterProxy primitiveFail].
- "stackArgvObject is something I added to Interpreter, but since it's not in there yet, - this won't compile - use it when it's there. Yes, it would be nice if Smalltalk had #ifdefs..." - self flag: #stackArgv. - " - srcOop := interpreterProxy stackArgvObject: 0. - src := interpreterProxy firstIndexableField: srcOop.
- dstOop := interpreterProxy stackArgvObject: 1. - dst := interpreterProxy firstIndexableField: dstOop. - " - srcOop := interpreterProxy stackObjectValue: argc. - src := interpreterProxy firstIndexableField: srcOop. - - dstOop := interpreterProxy stackObjectValue: (argc - 1). - dst := interpreterProxy firstIndexableField: dstOop. - - "read in the source matrix 3x3, which contains the encoded rotation and scale factors" m11 := src at: c11. m12 := src at: c12. m13 := src at: c13. m21 := src at: c21. m22 := src at: c22. m23 := src at: c23. m31 := src at: c31. m32 := src at: c32. m33 := src at: c33.
"read in the source translation vector" x := src at: c14. y := src at: c24. z := src at: c34.
"do the actual work"
"first, compute the determinant of the upper 3x3 of the source" det := ( m11 * ((m22 * m33) - (m23 * m32))) + (m12 * ((m23 * m31) - (m21 * m33))) + (m13 * ((m21 * m32) - (m22 * m31))).
"Compute the classical adjunct of the source, and divide by the source determinant storing in the destination. adjoint = transpose of cofactors, so we'll transpose as we store."
det := 1 / det. "let's make div by det a multiply" dst at: c11 put: ((m22 * m33) - (m23 * m32)) * det . dst at: c21 put: (0.0 - ((m21 * m33) - (m23 * m31))) * det. dst at: c31 put: ((m21 * m32) - (m22 * m31)) * det.
dst at: c12 put: (0.0 - ((m12 * m33) - (m13 * m32))) * det. dst at: c22 put: ((m11 * m33) - (m13 * m31)) * det. dst at: c32 put: (0.0 - ((m11 * m32) - (m12 * m31))) * det.
dst at: c13 put: ((m12 * m23) - (m13 * m22)) * det. dst at: c23 put: (0.0 - ((m11 * m23) - (m13 * m21))) * det. dst at: c33 put: ((m11 * m22) - (m12 * m21)) * det. "finally, apply the inversed rotation transform to our translation" "read in the source matrix 3x3" m11 := dst at: c11. m12 := dst at: c12. m13 := dst at: c13. m21 := dst at: c21. m22 := dst at: c22. m23 := dst at: c23. m31 := dst at: c31. m32 := dst at: c32. m33 := dst at: c33.
dst at: c14 put: 0.0 - ((x * m11) + (y * m12) + (z * m13)). dst at: c24 put: 0.0 - ((x * m21) + (y * m22) + (z * m23)). dst at: c34 put: 0.0 - ((x * m31) + (y * m32) + (z * m33)).
+ ^interpreterProxy methodReturnValue: dstOop! - interpreterProxy pop: argc + 1. - ^interpreterProxy push: dstOop. - !
Item was changed: ----- Method: CroquetPlugin>>primitiveMD5Transform (in category 'cryptography') ----- primitiveMD5Transform "Perform an MD5 transform of input" + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> "Align in case the compiler identifies and generates vector instructions" + | bufOop hashOop | + hashOop := interpreterProxy stackValue: 0. + bufOop := interpreterProxy stackValue: 1. + ((interpreterProxy isWords: hashOop) and: [(interpreterProxy slotSizeOf: hashOop) = 4 + and: [(interpreterProxy isWords: bufOop) and: [(interpreterProxy slotSizeOf: bufOop) = 16]]]) + ifFalse: + [^interpreterProxy primitiveFail]. - | bufOop hashOop hash buffer | - <export: true> - <var: 'hash' type: 'unsigned int *'> - <var: 'buffer' type: 'unsigned int *'> - interpreterProxy methodArgumentCount = 2 - ifFalse:[^interpreterProxy primitiveFail].
+ self MD5Transform: (interpreterProxy firstIndexableField: hashOop) _: (interpreterProxy firstIndexableField: bufOop). + ^interpreterProxy methodReturnValue: bufOop! - hashOop := interpreterProxy stackObjectValue: 0. - ((interpreterProxy isWords: hashOop) and:[(interpreterProxy slotSizeOf: hashOop) = 4]) - ifFalse:[^interpreterProxy primitiveFail]. - hash := interpreterProxy firstIndexableField: hashOop. - - bufOop := interpreterProxy stackObjectValue: 1. - ((interpreterProxy isWords: bufOop) and:[(interpreterProxy slotSizeOf: bufOop) = 16]) - ifFalse:[^interpreterProxy primitiveFail]. - buffer := interpreterProxy firstIndexableField: bufOop. - - - self cCode:'MD5Transform(hash, buffer)' inSmalltalk:[ - hash. buffer. - ^interpreterProxy primitiveFail]. - "Pop args; return buffer" - interpreterProxy pop: interpreterProxy methodArgumentCount+1. - ^interpreterProxy push: bufOop.!
Item was changed: ----- Method: CroquetPlugin>>primitiveOptimizeVertexIndicesForCacheLocality (in category 'mesh processing') ----- primitiveOptimizeVertexIndicesForCacheLocality "Given a list of integer indices for rendering a triangle-mesh in indexed-triangles mode, reorganize the indices in-place to provide better vertex cache locality. We use Tom Forsyth's algorithm: http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html ... and the MIT-licensed implementation by Michael Georgoulpoulos at: http://code.google.com/p/vcacne/" - | indicesOop indices byteSize triCount result | <export: true> + | indicesOop byteSize triCount | - <inline: true> - <var: #indices type: 'void *'>
+ indicesOop := interpreterProxy stackValue: 0. - "Get the oop of the IntegerArray containing the indices." - (interpreterProxy methodArgumentCount = 1) ifFalse: [^interpreterProxy primitiveFail]. - indicesOop := interpreterProxy stackObjectValue: 0. - interpreterProxy failed ifTrue: [^nil]. (interpreterProxy isWords: indicesOop) ifFalse: [^interpreterProxy primitiveFail]. "Ensure that the number of indices is a multiple of 3." byteSize := interpreterProxy byteSizeOf: indicesOop. + triCount := byteSize // 12. - triCount := byteSize / 12. (triCount * 12) = byteSize ifFalse: [^interpreterProxy primitiveFail]. + + "N.B. as of 8/2021 optimizeVertexIndices is simply a stub." + (self optimizeVertexIndices: (interpreterProxy firstIndexableField: indicesOop) _: triCount) ~= 0 ifTrue: + [^interpreterProxy primitiveFail]. + ^interpreterProxy methodReturnReceiver! - - "Get an int* to the indices, and optimize 'em." - indices := interpreterProxy firstIndexableField: indicesOop. - self touch: indices. - interpreterProxy failed ifTrue: [^nil]. - result := self cCode: 'optimizeVertexIndices((int*)indices, triCount)'. - result = 0 "success" ifFalse: [^interpreterProxy primitiveFail]. - ^interpreterProxy pop: 1!
Item was changed: ----- Method: CroquetPlugin>>primitiveOrthoNormInverseMatrix (in category 'transforms') ----- primitiveOrthoNormInverseMatrix + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> | srcOop dstOop src dst x y z rx ry rz | - <export: true> - <var: #src type: #'float *'> - <var: #dst type: #'float *'> <var: #x type: #double> <var: #y type: #double> <var: #z type: #double> <var: #rx type: #double> <var: #ry type: #double> <var: #rz type: #double>
+ srcOop := interpreterProxy stackValue: 0. + ((interpreterProxy isWords: srcOop) and:[(interpreterProxy slotSizeOf: srcOop) = 16]) ifFalse: + [^interpreterProxy primitiveFail]. - interpreterProxy methodArgumentCount = 0 - ifFalse:[^interpreterProxy primitiveFail]. - srcOop := interpreterProxy stackObjectValue: 0. - interpreterProxy failed ifTrue:[^nil]. - ((interpreterProxy isWords: srcOop) and:[(interpreterProxy slotSizeOf: srcOop) = 16]) - ifFalse:[^interpreterProxy primitiveFail]. dstOop := interpreterProxy cloneObject: srcOop. + dstOop = 0 ifTrue: + [^interpreterProxy primitiveFail]. "reload srcOop in case of GC" + self cppIf: #SPURVM ifFalse: [srcOop := interpreterProxy stackValue: 0]. + src := self cCoerce: (interpreterProxy firstIndexableField: srcOop) to: #'float *'. + dst := self cCoerce: (interpreterProxy firstIndexableField: dstOop) to: #'float *'. - srcOop := interpreterProxy stackObjectValue: 0. - src := interpreterProxy firstIndexableField: srcOop. - dst := interpreterProxy firstIndexableField: dstOop.
"Transpose upper 3x3 matrix" "dst at: 0 put: (src at: 0)." dst at: 1 put: (src at: 4). dst at: 2 put: (src at: 8). dst at: 4 put: (src at: 1). "dst at: 5 put: (src at: 5)." dst at: 6 put: (src at: 9). dst at: 8 put: (src at: 2). dst at: 9 put: (src at: 6). "dst at: 10 put: (src at: 10)."
"Compute inverse translation vector" x := src at: 3. y := src at: 7. z := src at: 11. rx := (x * (dst at: 0)) + (y * (dst at: 1)) + (z * (dst at: 2)). ry := (x * (dst at: 4)) + (y * (dst at: 5)) + (z * (dst at: 6)). rz := (x * (dst at: 8)) + (y * (dst at: 9)) + (z * (dst at: 10)).
+ dst at: 3 put: 0.0 - rx. + dst at: 7 put: 0.0 - ry. + dst at: 11 put: 0.0 - rz. - dst at: 3 put: (self cCoerce: 0.0-rx to: #float). - dst at: 7 put: (self cCoerce: 0.0-ry to: #float). - dst at: 11 put: (self cCoerce: 0.0-rz to: #float).
+ ^interpreterProxy methodReturnValue: dstOop! - interpreterProxy pop: 1 thenPush: dstOop!
Item was changed: ----- Method: CroquetPlugin>>primitiveTransformDirection (in category 'transforms') ----- primitiveTransformDirection + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> | x y z rx ry rz matrix vertex v3Oop | + <var: #x type: #double> + <var: #y type: #double> + <var: #z type: #double> + <var: #rx type: #double> + <var: #ry type: #double> + <var: #rz type: #double> - <export: true> - <var: #vertex declareC:'float *vertex'> - <var: #matrix declareC:'float *matrix'> - <var: #x declareC:'double x'> - <var: #y declareC:'double y'> - <var: #z declareC:'double z'> - <var: #rx declareC:'double rx'> - <var: #ry declareC:'double ry'> - <var: #rz declareC:'double rz'>
- interpreterProxy methodArgumentCount = 1 - ifFalse:[^interpreterProxy primitiveFail]. - v3Oop := interpreterProxy stackObjectValue: 0. - interpreterProxy failed ifTrue:[^nil]. - ((interpreterProxy isWords: v3Oop) and:[(interpreterProxy slotSizeOf: v3Oop) = 3]) - ifFalse:[^interpreterProxy primitiveFail]. - vertex := interpreterProxy firstIndexableField: v3Oop. matrix := self stackMatrix: 1. + v3Oop := interpreterProxy stackValue: 0. + (matrix notNil and: [(interpreterProxy isWords: v3Oop) and:[(interpreterProxy slotSizeOf: v3Oop) = 3]]) ifFalse: + [^interpreterProxy primitiveFail]. + vertex := self cCoerce: (interpreterProxy firstIndexableField: v3Oop) to: #'float *'. - (matrix == nil) ifTrue:[^interpreterProxy primitiveFail].
x := vertex at: 0. y := vertex at: 1. z := vertex at: 2.
rx := (x * (matrix at: 0)) + (y * (matrix at: 1)) + (z * (matrix at: 2)). ry := (x * (matrix at: 4)) + (y * (matrix at: 5)) + (z * (matrix at: 6)). rz := (x * (matrix at: 8)) + (y * (matrix at: 9)) + (z * (matrix at: 10)).
v3Oop := interpreterProxy cloneObject: v3Oop. + v3Oop = 0 ifTrue: + [^interpreterProxy primitiveFailFor: PrimErrNoMemory]. + vertex := self cCoerce: (interpreterProxy firstIndexableField: v3Oop) to: #'float *'. - vertex := interpreterProxy firstIndexableField: v3Oop.
+ vertex at: 0 put: rx. + vertex at: 1 put: ry. + vertex at: 2 put: rz. - vertex at: 0 put: (self cCoerce: rx to: 'float'). - vertex at: 1 put: (self cCoerce: ry to:'float'). - vertex at: 2 put: (self cCoerce: rz to: 'float').
+ ^interpreterProxy methodReturnValue: v3Oop! - interpreterProxy pop: 2. - ^interpreterProxy push: v3Oop. - !
Item was changed: ----- Method: CroquetPlugin>>primitiveTransformMatrixWithInto (in category 'transforms') ----- primitiveTransformMatrixWithInto "Transform two matrices into the third" + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> | m1 m2 m3 | - <export: true> - <inline: false> - <var: #m1 declareC:'float *m1'> - <var: #m2 declareC:'float *m2'> - <var: #m3 declareC:'float *m3'>
m3 := self stackMatrix: 0. m2 := self stackMatrix: 1. m1 := self stackMatrix: 2. + (m1 isNil or: [m2 isNil or: [m3 isNil + or: [m2 = m3]]]) ifTrue: + [^interpreterProxy primitiveFail]. - (m1 = nil) | (m2 = nil) | (m3 = nil) - ifTrue:[^interpreterProxy primitiveFail]. - m2 == m3 ifTrue:[^interpreterProxy primitiveFail]. self transformMatrix: m1 with: m2 into: m3. + ^interpreterProxy methodReturnReceiver! - ^interpreterProxy pop: 3. "Leave rcvr on stack"!
Item was changed: ----- Method: CroquetPlugin>>primitiveTransformVector3 (in category 'transforms') ----- primitiveTransformVector3 + <export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)> | x y z rx ry rz rw matrix vertex v3Oop | + <var: #x type: #double> + <var: #y type: #double> + <var: #z type: #double> + <var: #rx type: #double> + <var: #ry type: #double> + <var: #rz type: #double> + <var: #rw type: #double> - <export: true> - <var: #vertex declareC:'float *vertex'> - <var: #matrix declareC:'float *matrix'> - <var: #x declareC:'double x'> - <var: #y declareC:'double y'> - <var: #z declareC:'double z'> - <var: #rx declareC:'double rx'> - <var: #ry declareC:'double ry'> - <var: #rz declareC:'double rz'> - <var: #rw declareC:'double rw'>
- interpreterProxy methodArgumentCount = 1 - ifFalse:[^interpreterProxy primitiveFail]. - v3Oop := interpreterProxy stackObjectValue: 0. - interpreterProxy failed ifTrue:[^nil]. - ((interpreterProxy isWords: v3Oop) and:[(interpreterProxy slotSizeOf: v3Oop) = 3]) - ifFalse:[^interpreterProxy primitiveFail]. - vertex := interpreterProxy firstIndexableField: v3Oop. matrix := self stackMatrix: 1. + v3Oop := interpreterProxy stackValue: 0. + (matrix notNil and: [(interpreterProxy isWords: v3Oop) and:[(interpreterProxy slotSizeOf: v3Oop) = 3]]) ifFalse: + [^interpreterProxy primitiveFail]. + vertex := self cCoerce: (interpreterProxy firstIndexableField: v3Oop) to: #'float *'. - (matrix == nil) ifTrue:[^interpreterProxy primitiveFail].
x := vertex at: 0. y := vertex at: 1. z := vertex at: 2.
rx := (x * (matrix at: 0)) + (y * (matrix at: 1)) + (z * (matrix at: 2)) + (matrix at: 3). ry := (x * (matrix at: 4)) + (y * (matrix at: 5)) + (z * (matrix at: 6)) + (matrix at: 7). rz := (x * (matrix at: 8)) + (y * (matrix at: 9)) + (z * (matrix at: 10)) + (matrix at: 11). rw := (x * (matrix at: 12)) + (y * (matrix at: 13)) + (z * (matrix at: 14)) + (matrix at: 15).
v3Oop := interpreterProxy cloneObject: v3Oop. + v3Oop = 0 ifTrue: + [^interpreterProxy primitiveFailFor: PrimErrNoMemory]. + vertex := self cCoerce: (interpreterProxy firstIndexableField: v3Oop) to: #'float *'. - vertex := interpreterProxy firstIndexableField: v3Oop.
rw = 1.0 ifTrue:[ + vertex at: 0 put: rx. + vertex at: 1 put: ry. + vertex at: 2 put: rz. - vertex at: 0 put: (self cCoerce: rx to: 'float'). - vertex at: 1 put: (self cCoerce: ry to:'float'). - vertex at: 2 put: (self cCoerce: rz to: 'float'). ] ifFalse:[ rw = 0.0 ifTrue:[rw := 0.0] ifFalse:[rw := 1.0 / rw]. + vertex at: 0 put: rx * rw. + vertex at: 1 put: ry * rw. + vertex at: 2 put: rz * rw. - vertex at: 0 put: (self cCoerce: rx*rw to:'float'). - vertex at: 1 put: (self cCoerce: ry*rw to:'float'). - vertex at: 2 put: (self cCoerce: rz*rw to: 'float'). ]. + ^interpreterProxy methodReturnValue: v3Oop! - interpreterProxy pop: 2. - ^interpreterProxy push: v3Oop. - !
Item was changed: ----- Method: CroquetPlugin>>primitiveTriBoxIntersects (in category 'transforms') ----- primitiveTriBoxIntersects "Primitive. Answer whether an AABB intersects with a given triangle" | minCorner maxCorner v0 v1 v2 result | - <export: true> - <var: #minCorner type: #'float *'> - <var: #maxCorner type: #'float *'> - <var: #v0 type: #'float *'> - <var: #v1 type: #'float *'> - <var: #v2 type: #'float *'>
- interpreterProxy methodArgumentCount = 5 - ifFalse:[^interpreterProxy primitiveFail]. v2 := self stackVector3: 0. v1 := self stackVector3: 1. v0 := self stackVector3: 2. maxCorner := self stackVector3: 3. minCorner := self stackVector3: 4.
+ (v0 isNil or: [v1 isNil or: [v2 isNil + or: [maxCorner isNil or: [minCorner isNil]]]]) ifTrue: + [^interpreterProxy primitiveFail]. + "N.B. as of 8/2021 triBoxOverlap is simply a stub." + result := self triBoxOverlap: minCorner _: maxCorner _: v0 _: v1 _: v2. - result := self cCode:'triBoxOverlap(minCorner, maxCorner, v0, v1, v2)' - inSmalltalk:[minCorner. maxCorner. v0. v1. v2. -1]. result < 0 ifTrue:[^interpreterProxy primitiveFail]. + ^interpreterProxy methodReturnBool: result > 0! - - interpreterProxy pop: 6. "args+rcvr" - ^interpreterProxy pushBool: result.!
Item was changed: ----- Method: CroquetPlugin>>stackMatrix: (in category 'transforms') ----- stackMatrix: index "Load a 4x4 transformation matrix from the interpreter stack. Return a pointer to the matrix data if successful, nil otherwise." + <returnTypeC: #'float *'> | oop | + <inline: #always> + oop := interpreterProxy stackValue: index. + ^((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 16]) ifTrue: + [self cCoerce: (interpreterProxy firstIndexableField: oop) to: #'float *']! - <inline: false> - returnTypeC:'void*' - oop := interpreterProxy stackObjectValue: index. - oop = nil ifTrue:[^nil]. - ((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 16]) - ifTrue:[^interpreterProxy firstIndexableField: oop]. - ^nil!
Item was changed: ----- Method: CroquetPlugin>>stackVector3: (in category 'transforms') ----- stackVector3: index "Load a Vector3 from the interpreter stack. Return a pointer to the float data if successful, nil otherwise." + <returnTypeC: #'float *'> | oop | + <inline: #always> + oop := interpreterProxy stackValue: index. + ^((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 3]) ifTrue: + [self cCoerce: (interpreterProxy firstIndexableField: oop) to: #'float *']! - <inline: false> - returnTypeC:'void*' - oop := interpreterProxy stackObjectValue: index. - oop = nil ifTrue:[^nil]. - ((interpreterProxy isWords: oop) and:[(interpreterProxy slotSizeOf: oop) = 3]) - ifTrue:[^interpreterProxy firstIndexableField: oop]. - ^nil!
Item was changed: ----- Method: CroquetPlugin>>transformMatrix:with:into: (in category 'transforms') ----- transformMatrix: src with: arg into: dst "Transform src with arg into dst. It is allowed that src == dst but not arg == dst" + <var: #src type: #'float *'> + <var: #arg type: #'float *'> + <var: #dst type: #'float *'> | m1 m2 m3 c1 c2 c3 c4 | + <var: #m1 type: #'float *'> + <var: #m2 type: #'float *'> + <var: #m3 type: #'float *'> - <var: #src declareC:'float *src'> - <var: #arg declareC:'float *arg'> - <var: #dst declareC:'float *dst'> - <var: #m1 declareC:'float *m1'> - <var: #m2 declareC:'float *m2'> - <var: #m3 declareC:'float *m3'>
+ <var: #c1 type: #double> + <var: #c2 type: #double> + <var: #c3 type: #double> + <var: #c4 type: #double> - <var: #c1 declareC:'double c1'> - <var: #c2 declareC:'double c2'> - <var: #c3 declareC:'double c3'> - <var: #c4 declareC:'double c4'>
+ m1 := self cCoerce: src to: #'float *'. + m2 := self cCoerce: arg to: #'float *'. + m3 := self cCoerce: dst to: #'float *'. - m1 := self cCoerce: src to:'float *'. - m2 := self cCoerce: arg to: 'float *'. - m3 := self cCoerce: dst to: 'float *'.
0 to: 3 do:[:i|
"Compute next row" + c1 := ((m1 at: 0) * (m2 at: 0)) + ((m1 at: 1) * (m2 at: 4)) + + ((m1 at: 2) * (m2 at: 8)) + ((m1 at: 3) * (m2 at: 12)). - c1 := ((m1 at: 0) asFloat * (m2 at: 0) asFloat) + ((m1 at: 1) asFloat * (m2 at: 4) asFloat) + - ((m1 at: 2) asFloat * (m2 at: 8) asFloat) + ((m1 at: 3) asFloat * (m2 at: 12) asFloat).
+ c2 := ((m1 at: 0) * (m2 at: 1)) + ((m1 at: 1) * (m2 at: 5)) + + ((m1 at: 2) * (m2 at: 9)) + ((m1 at: 3) * (m2 at: 13)). - c2 := ((m1 at: 0) asFloat * (m2 at: 1) asFloat) + ((m1 at: 1) asFloat * (m2 at: 5) asFloat) + - ((m1 at: 2) asFloat * (m2 at: 9) asFloat) + ((m1 at: 3) asFloat * (m2 at: 13) asFloat).
+ c3 := ((m1 at: 0) * (m2 at: 2)) + ((m1 at: 1) * (m2 at: 6)) + + ((m1 at: 2) * (m2 at: 10)) + ((m1 at: 3) * (m2 at: 14)). - c3 := ((m1 at: 0) asFloat * (m2 at: 2) asFloat) + ((m1 at: 1) asFloat * (m2 at: 6) asFloat) + - ((m1 at: 2) asFloat * (m2 at: 10) asFloat) + ((m1 at: 3) asFloat * (m2 at: 14) asFloat).
+ c4 := ((m1 at: 0) * (m2 at: 3)) + ((m1 at: 1) * (m2 at: 7)) + + ((m1 at: 2) * (m2 at: 11)) + ((m1 at: 3) * (m2 at: 15)). - c4 := ((m1 at: 0) asFloat * (m2 at: 3) asFloat) + ((m1 at: 1) asFloat * (m2 at: 7) asFloat) + - ((m1 at: 2) asFloat * (m2 at: 11) asFloat) + ((m1 at: 3) asFloat * (m2 at: 15) asFloat).
"Store result" m3 at: 0 put: c1. m3 at: 1 put: c2. m3 at: 2 put: c3. m3 at: 3 put: c4.
"Skip src and dst to next row" m1 := m1 + 4. m3 := m3 + 4. ].
^nil !
vm-dev@lists.squeakfoundation.org