In depth 1, the resulting bits will always be 0.<br>
It's not a big problem because rgbMul is just a bitAnd operation at this depth.<br>
So a quick workaround would be to detect the case in BitBltSimulation
destDepth = 1 ifTrue: [^self bitAnd: sourceWord with: destinationWord].
That would also accelerate the Bit BLock Transfer operation, so it's a good hack.
But there is more. What we want is multiply ratios in interval [0,1].
dstRatio * srcRatio
Our implementation is scaled ratio (scaled by `1 << nBits - 1`):
src := (srcRatio * scale) rounded.
dst := (dstRatio * scale) rounded.
So what we want is:
((dst/scale) * (src/scale) * scale) rounded
that is:
(dst*src / (1<<nBits-1)) rounded
Unfortunately, that's the other grief with the current implementation used for rounding:
(dst+1)*(src+1) - 1 >> nBits
It only equals correctly rounded operation for depths 2 and 4.
For rounding we might use:
(((dst/scale) * (src/scale) + 0.5) * scale) truncated.
that is expressed with truncated division:
dst*src + (scale+1//2) // scale
So here is a nicer formulation for doing the job at any depth (including 5bits rgb channels for 16 bits depth) with correctly rounded division:
aux := src * dst + (1 << (nBits - 1)). "add mid-scale for rounding"
result := aux << (nBits - 1) + aux << (nBits -1). "divide by scale"
This is because instead of dividing by scale, we can multiply by shifted inverse (sort of double precision), then shift right.
(2 to: 32) allSatisfy: [:nBits | (1 << (nBits * 2) / (1 << nBits - 1)) rounded = (1 << nBits + 1)].
Multiplying by this inverse is easy and cheap:
x * (1 << nBits + 1) = (x << nBits + x).
And then applying the right shift `>> (2 * nBits)` is equivalent to:
x >> nBits + x >> nBits.
We must first add 0.5 (scaled), that is `src * dst + (1 << (nBits -1))` - our formulation of aux, and we're done.
We verify:
{
(0 to: 1<<20-1) allSatisfy: [:i | (1<<9+i)>>10+ (1<<9+i)>>10 = (i/1023) rounded].
(0 to: 1<<18-1) allSatisfy: [:i | (1<<8+i)>>9+ (1<<8+i)>>9 = (i/511) rounded].
(0 to: 1<<16-1) allSatisfy: [:i | (1<<7+i)>>8+ (1<<7+i)>>8 = (i/255) rounded].
(0 to: 1<<14-1) allSatisfy: [:i | (1<<6+i)>>7+ (1<<6+i)>>7 = (i/127) rounded].
(0 to: 1<<12-1) allSatisfy: [:i | (1<<5+i)>>6+ (1<<5+i)>>6 = (i/63) rounded].
(0 to: 1<<10-1) allSatisfy: [:i | (1<<4+i)>>5+ (1<<4+i)>>5 = (i/31) rounded].
(0 to: 1<<8-1) allSatisfy: [:i | (1<<3+i)>>4+ (1<<3+i)>>4 = (i/15) rounded].
(0 to: 1<<6-1) allSatisfy: [:i | (1<<2+i)>>3+ (1<<2+i)>>3 = (i/7) rounded].
(0 to: 1<<4-1) allSatisfy: [:i | (1<<1+i)>>2+ (1<<1+i)>>2 = (i/3) rounded].
} allSatisfy: #yourself.
The nice thing is that above down-scaling operation can be multiplexed.<b>
Suppose that we have p groups of 2*nBits `M` holding square-scale multiplication of each channel concatenated in a double-Word-Mul.
doubleWordMul = Mp .... M5 M3 M1
Note we arrange to have odd channels in low word, and even channels in high word.
We first form a `groupMask` on a word with (p+1)/2 groups of nBits alternating all one `i` and all zero `o`, `oioi...ioi`.<br>
channelMask := 1 << nBits - 1.
groupMask := 0.
0 to: wordBits // (2 * nBits) do: [:i |
groupMask = groupMask << (2 * nBits) + channelMask].
Where wordBits is the number of bits in a word (usually we want to operate on 32 bits words in BitBlt).
We form the `doubleGroupMask` on a double-word with p groups of 2*nBits `oi`:
doubleGroupMask := groupMask >> nBits.
doubleGroupMask := doubleGroupMask << wordBits + groupMask.
And we perform the division by scale:
doubleWordMul := (doubleWordMul >> nBits bitAnd: doubleGroupMask) + doubleWord >> nBits bitAnd: doubleGroupMask.
At this stage we obtain a double word containing scaled multiplicands interleaved with groups of nBits zeros:
o mp ... o m3 o m1
Now the final result can be obtained by shifting back:
doubleWordMul >> (wordBits - nBits) + (doubleWordMul bitAnd: groupMask)
The only problem remaining is how to obtain the squared-scale multiplicands. It would be easy to form the alternate even-odd channels for each src and dst operands:
doubleWordSrc := src >> nBits bitAnd: groupMask.
doubleWordSrc := doubleWordSrc << wordBits + (src bitAnd: groupMask).
doubleWordDst := dst >> nBits bitAnd: groupMask.
doubleWordDst := doubleWordDst << wordBits + (dst bitAnd: groupMask).
we now get `o sp ... o s3 o s1` and `0 dp ... o d3 o d1`, but we would now need a SIMD integer multiplication operating on groups of 2*nBits in parallel... We don't have that, at least in portable C code. So we still have to emulate it with a loop.
half := 1 << (nBits - 1).
shift := 0.
doubleWordMul := 0
0 to: nChannels - 1 do: [:i |
doubleWordMul := doubleWordMul + (((doubleWordSrc >> shift bitAnd: channelMask) * (doubleWordSrc >> shift bitAnd: channelMask) + half) << shift).
shift := shift + nBits + nBits].
We know that each operation cannot overflow on upper neighbour group of 2*nBits, because the maximum value is:
(1<<nBits-1) squared + (1 << (nBits-1)) = 1 << (2*nBits) - (2*(1<<nBits)) + (1 << (nBits-1)) - 1
< (1 << (2*nBits) - 1)
It remains the odd case of 16 bits depth, which has 3 groups of 5 bits and a leading zero.
I believe that above algorithm works without splitting in two half-words...
To be tested.
We have gathered the pieces for a correctly rounded almost-multiplexed rgbMul.<br>
Somehow have our cake and eat it too.
--
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/651
You are receiving this because you are subscribed to this thread.
Message ID: <OpenSmalltalk/opensmalltalk-vm/issues/651(a)github.com>
===== PX/23 Call for Papers =====
Submissions possible until Mon 16 Jan 2023 :)
Welcome to the 9th Edition of the Programming Experience Workshop
https://2023.programming-conference.org/home/px-2023
Co-located with <Programming> 2023 in Tokyo
https://2023.programming-conference.org/
## Abstract
Some programming feels fun, other programming feels annoying. Why?
For a while now the study of programming has forced improvements to be described through the Fordist lens of usability and productivity, where the thing that matters is how much software can get built, how quickly.
But along the way, something has gone missing. What makes programmers feel the way they do when they’re programming? It’s not usually fun to spend an age doing something that could have been done easily, so efficiency and usability still matter, but they’re not the end of the story.
Some environments, activities, contexts, languages, infrastructures make programming feel alive, others feel like working in a bureaucracy. This is not purely technologically determined, writing Lisp to do your taxes probably still isn’t fun, but it’s also not technologically neutral, writing XML to produce performance art is still likely to be <bureaucratic></bureaucratic>.
Whilst we can probably mostly agree about what isn’t fun, what is remains more personal and without a space within the academy to describe it.
In its past editions, PX set its focus on questions like: Do programmers create text that is transformed into running behavior (the old way), or do they operate on behavior directly (“liveness”); are they exploring the live domain to understand the true nature of the requirements; are they like authors creating new worlds; does visualization matter; is the experience immediate, immersive, vivid and continuous; do fluency, literacy, and learning matter; do they build tools, meta-tools; are they creating languages to express new concepts quickly and easily; and curiously, is joy relevant to the experience?
In this 9th edition of PX, we will expand its focus to also cover the experience that programmers have. What makes it and what breaks it? For whom? What can we build to share the joy of programming with others?
Here is a list of topic areas to get you thinking:
- creating programs
- experience of programming
- exploratory programming
- liveness
- non-standard tools
- visual, auditory, tactile, and other non-textual languages
- text and more than text
- program understanding
- domain-specific languages
- psychology of programming
- error tolerance
- user studies
- theories about all that
Correctness, performance, standard tools, foundations, and text-as-program are important traditional research areas, but the experience of programming and how to improve and evolve it are the focus of this workshop. We also welcome a wide spectrum of contributions on programming experience.
## Submissions
Submissions are solicited for Programming Experience 2023 (PX/23). The thrust of the workshop is to explore the human experience of programming—what it feels like to program, or what it should feel like. The technical topics include exploratory programming, live programming, authoring, representation of active content, visualization, navigation, modularity mechanisms, immediacy, literacy, fluency, learning, tool building, language engineering, and theory building.
Submissions by academics, professional programmers, and non-professional programmer are welcome. Submissions can be in any form and format, including but not limited to papers, presentations, demos, videos, panels, debates, essays, writers’ workshops, and art. Presentation slots are expected to be between 20 minutes and one hour (if time allows), depending on quality, form, and relevance to the workshop.
Submissions of academic papers directed toward publication should be so marked, and the program committee will engage in peer review for all such papers.
All artifacts are to be submitted via EasyChair [2]. Papers and essays must be written in English, provided as PDF documents, and strictly adhere to the ACM Format [3]. [...]
## Review
Submissions of academic papers directed toward publication will undergo standard peer review; other submissions will be reviewed for relevance and quality; shepherding will be available.
## Publication
Academic papers and essays accepted for publication will be published as part of ACM's Digital Library; video publication on Vimeo or other streaming site; other publication on the PX workshop website.
## Upcoming Deadlines (AoE)
Submissions:
Mon 16 Jan 2023
Notifications:
Mon 6 Feb 2023
Pre-workshop versions:
Mon 20 Feb 2023
Workshop (hybrid/online):
Mon 13 or Tue 14 Mar 2023
Final versions:
Mon 3 Apr 2023
## More Information
[1] https://2023.programming-conference.org/home/px-2023
[2] https://easychair.org/conferences/?conf=px23
[3] http://www.acm.org/publications/proceedings-template
Hi all!
Has anybody tried to build OSVM in Windows 11 via Cygwin64?
clang-8 does not work because "_alloca" cannot be found ... hmm...
So, who implements _alloca? It's not msvcrt.dll ... how to find that out?
Best,
Marcel
David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.437.mcz
==================== Summary ====================
Name: VMMaker-dtl.437
Author: dtl
Time: 30 December 2022, 5:13:52.807 pm
UUID: 720c8b4b-1edc-4154-8f0e-dfb30db137a7
Ancestors: VMMaker-dtl.436
VMMaker 4.20.3
Document and fix an ancient bug in return type generation for inlined methods. Symptom was duplicate (float *) casts in generated KlattSynthesizerPlugin>>loadFrom: when code was generated from a Squeak 6 image (worked by accident in Squeak 4.6). Add unit test to document the bug and fix it in CCodeGenerator>>collectInlineList.
=============== Diff against VMMaker-dtl.436 ===============
Item was changed:
----- Method: CCodeGenerator>>collectInlineList (in category 'inlining') -----
collectInlineList
"Make a list of methods that should be inlined."
"Details: The method must not include any inline C, since the translator cannot
currently map variable names in inlined C code. The #inline: directive may be
used to override this for cases in which the C code or declarations are harmless.
Methods to be inlined must be small or called from only one place."
| methodsNotToInline callsOf inlineIt hasCCode nodeCount senderCount
sel returnTypesOf |
methodsNotToInline := Set new: methods size.
"build dictionary to record the number of calls to each method"
callsOf := Dictionary new: methods size * 2.
returnTypesOf := Dictionary new: methods size.
methods keys do: [ :s | callsOf at: s put: 0 ].
methods do: [ :m | returnTypesOf at: m selector put: m returnType ].
"For each method, scan its parse tree once to:
1. determine if the method contains C code or declarations
2. determine how many nodes it has
3. increment the sender counts of the methods it calls
4. determine if it includes any C declarations or code"
inlineList := Set new: methods size * 2.
inlineReturnTypes := Dictionary new: methods size.
methods do: [ :m |
inlineIt := #dontCare.
(translationDict includesKey: m selector) ifTrue: [
hasCCode := true.
] ifFalse: [
hasCCode := m declarations size > 0.
nodeCount := 0.
m parseTree nodesDo: [ :node |
node isSend ifTrue: [
sel := node selector.
(sel = #cCode: or: [sel = #cCode:inSmalltalk:])
ifTrue: [ hasCCode := true ].
senderCount := callsOf at: sel ifAbsent: [ nil ].
nil = senderCount ifFalse: [
callsOf at: sel put: senderCount + 1.
].
].
nodeCount := nodeCount + 1.
].
inlineIt := m extractInlineDirective. "may be true, false, or
#dontCare"
].
(inlineIt ~= true and: [hasCCode or: [inlineIt = false]]) ifTrue: [
"Don't inline if method has C code or if it contains a negative inline
directive. If it contains a positive inline directive, permit inlining even
if C code is present."
methodsNotToInline add: m selector.
] ifFalse: [
((nodeCount < 40) or: [inlineIt = true]) ifTrue: [
+ "inline if method has no C code and is either small or contains inline directive"
- "inline if method has no C code and is either small or contains
- inline directive"
inlineList add: m selector.
+ inlineReturnTypes at: m selector put: m returnType.
- inlineReturnTypes at: sel put: m returnType.
].
].
].
callsOf associationsDo: [ :assoc |
((assoc value = 1) and: [(methodsNotToInline includes: assoc key)
not]) ifTrue: [
inlineList add: assoc key.
].
].!
Item was added:
+ ----- Method: SlangTest>>testTwoInlinedCCoerceInOneMethod (in category 'testing variable declaration') -----
+ testTwoInlinedCCoerceInOneMethod
+ "Pattern appearing in KlattPlugin>>loadFrom:
+ Translated C code should have one type cast (not two)."
+
+ | stssi s |
+ stssi := SlangTestSupportPlugin inline: true.
+ s := stssi asCString: #testTwoInlinedCCoerceInOneMethod .
+ self should: ('*floatPointer = ((float *) (interpreterProxy->firstIndexableField(12345)));*' match: s).
+ self should: ('*shortPointer = ((short *) (interpreterProxy->firstIndexableField(789)));*' match: s).!
Item was changed:
InterpreterPlugin subclass: #SlangTestSupportPlugin
+ instanceVariableNames: 'cg inlineFlag floatPointer shortPointer'
- instanceVariableNames: 'cg inlineFlag'
classVariableNames: ''
poolDictionaries: ''
category: 'VMMaker-Tests'!
!SlangTestSupportPlugin commentStamp: 'dtl 9/19/2010 21:36' prior: 0!
SlangTestSupport implements translatable methods for use in SlangTest unit tests.
This is a subclass of InterpreterPlugin, which provides coverage of slang translation
for base plugins.
"VMMaker clearCacheEntriesFor: SlangTestSupportPlugin.
SlangTestSupportPlugin asCString"!
Item was added:
+ ----- Method: SlangTestSupportPlugin class>>declareCVarsIn: (in category 'translation') -----
+ declareCVarsIn: cg
+ cg var: #floatPointer type: #'float *'.
+ cg var: #shortPointer type: #'short *'.
+ !
Item was added:
+ ----- Method: SlangTestSupportPlugin>>checkedFloatPtrOf: (in category 'type declaration') -----
+ checkedFloatPtrOf: oop
+ "Originally implemented (ar) in FFTPlugin, also found in KlattPlugin, copied here for testing"
+ "Return the first indexable word of oop which is assumed to be variableWordSubclass"
+ <returnTypeC:'float *'>
+ interpreterProxy success: (interpreterProxy isWords: oop).
+ interpreterProxy failed ifTrue:[^0].
+ ^self cCoerce: (interpreterProxy firstIndexableField: oop) to:'float *'!
Item was added:
+ ----- Method: SlangTestSupportPlugin>>checkedShortPtrOf: (in category 'type declaration') -----
+ checkedShortPtrOf: oop
+ "Originally implemented in FFTPlugin, also found in KlattPlugin, copied here for testing"
+ "Return the first indexable word of oop which is assumed to be variableWordSubclass"
+ <returnTypeC: 'short *'>
+ interpreterProxy success: (interpreterProxy isWords: oop).
+ interpreterProxy failed ifTrue:[^0].
+ ^self cCoerce: (interpreterProxy firstIndexableField: oop) to:'short *'!
Item was added:
+ ----- Method: SlangTestSupportPlugin>>testTwoInlinedCCoerceInOneMethod (in category 'type declaration') -----
+ testTwoInlinedCCoerceInOneMethod
+ "Pattern appearing in KlattPlugin>>loadFrom:
+ Translated C code should have one type cast (not two)"
+
+ <export: true>
+ shortPointer := self checkedShortPtrOf: 789..
+ floatPointer := self checkedFloatPtrOf: 12345..
+ !
Item was changed:
----- Method: VMMaker class>>versionString (in category 'version testing') -----
versionString
"VMMaker versionString"
+ ^'4.20.3'!
- ^'4.20.2'!
David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.437.mcz
==================== Summary ====================
Name: VMMaker-dtl.437
Author: dtl
Time: 30 December 2022, 2:51:02.319 pm
UUID: 021734cc-f299-460b-833e-f547874175af
Ancestors: VMMaker-dtl.436
VMMaker 4.20.3
Document and fix an ancient bug in return type generation for inlined methods. Symptom was duplicate (float *) casts in generated KlattSynthesizerPlugin>>loadFrom: when code was generated from a Squeak 6 image (worked by accident in Squeak 4.6). Add unit test to document the bug and fix it in CCodeGenerator>>collectInlineList.
=============== Diff against VMMaker-dtl.436 ===============
Item was changed:
----- Method: CCodeGenerator>>collectInlineList (in category 'inlining') -----
collectInlineList
"Make a list of methods that should be inlined."
"Details: The method must not include any inline C, since the translator cannot
currently map variable names in inlined C code. The #inline: directive may be
used to override this for cases in which the C code or declarations are harmless.
Methods to be inlined must be small or called from only one place."
| methodsNotToInline callsOf inlineIt hasCCode nodeCount senderCount
sel returnTypesOf |
methodsNotToInline := Set new: methods size.
"build dictionary to record the number of calls to each method"
callsOf := Dictionary new: methods size * 2.
returnTypesOf := Dictionary new: methods size.
methods keys do: [ :s | callsOf at: s put: 0 ].
methods do: [ :m | returnTypesOf at: m selector put: m returnType ].
"For each method, scan its parse tree once to:
1. determine if the method contains C code or declarations
2. determine how many nodes it has
3. increment the sender counts of the methods it calls
4. determine if it includes any C declarations or code"
inlineList := Set new: methods size * 2.
inlineReturnTypes := Dictionary new: methods size.
methods do: [ :m |
inlineIt := #dontCare.
(translationDict includesKey: m selector) ifTrue: [
hasCCode := true.
] ifFalse: [
hasCCode := m declarations size > 0.
nodeCount := 0.
m parseTree nodesDo: [ :node |
node isSend ifTrue: [
sel := node selector.
(sel = #cCode: or: [sel = #cCode:inSmalltalk:])
ifTrue: [ hasCCode := true ].
senderCount := callsOf at: sel ifAbsent: [ nil ].
nil = senderCount ifFalse: [
callsOf at: sel put: senderCount + 1.
].
].
nodeCount := nodeCount + 1.
].
inlineIt := m extractInlineDirective. "may be true, false, or
#dontCare"
].
(inlineIt ~= true and: [hasCCode or: [inlineIt = false]]) ifTrue: [
"Don't inline if method has C code or if it contains a negative inline
directive. If it contains a positive inline directive, permit inlining even
if C code is present."
methodsNotToInline add: m selector.
] ifFalse: [
((nodeCount < 40) or: [inlineIt = true]) ifTrue: [
"inline if method has no C code and is either small or contains
inline directive"
inlineList add: m selector.
+ "('CCoerce*' match: sel) ifTrue: [self halt]."
+ inlineReturnTypes at: m selector put: m returnType.
+
+
+ " inlineReturnTypes at: sel put: m returnType."
- inlineReturnTypes at: sel put: m returnType.
].
].
].
callsOf associationsDo: [ :assoc |
((assoc value = 1) and: [(methodsNotToInline includes: assoc key)
not]) ifTrue: [
inlineList add: assoc key.
].
].!
Item was added:
+ ----- Method: SlangTest>>testTwoInlinedCCoerceInOneMethod (in category 'testing variable declaration') -----
+ testTwoInlinedCCoerceInOneMethod
+ "Pattern appearing in KlattPlugin>>loadFrom:
+ Translated C code should have one type cast (not two)."
+
+ | stssi s |
+ stssi := SlangTestSupportPlugin inline: true.
+ s := stssi asCString: #testTwoInlinedCCoerceInOneMethod .
+ self should: ('*floatPointer = ((float *) (interpreterProxy->firstIndexableField(12345)));*' match: s).
+ self should: ('*shortPointer = ((short *) (interpreterProxy->firstIndexableField(789)));*' match: s).!
Item was changed:
InterpreterPlugin subclass: #SlangTestSupportPlugin
+ instanceVariableNames: 'cg inlineFlag floatPointer shortPointer'
- instanceVariableNames: 'cg inlineFlag'
classVariableNames: ''
poolDictionaries: ''
category: 'VMMaker-Tests'!
!SlangTestSupportPlugin commentStamp: 'dtl 9/19/2010 21:36' prior: 0!
SlangTestSupport implements translatable methods for use in SlangTest unit tests.
This is a subclass of InterpreterPlugin, which provides coverage of slang translation
for base plugins.
"VMMaker clearCacheEntriesFor: SlangTestSupportPlugin.
SlangTestSupportPlugin asCString"!
Item was added:
+ ----- Method: SlangTestSupportPlugin class>>declareCVarsIn: (in category 'translation') -----
+ declareCVarsIn: cg
+ cg var: #floatPointer type: #'float *'.
+ cg var: #shortPointer type: #'short *'.
+ !
Item was added:
+ ----- Method: SlangTestSupportPlugin>>checkedFloatPtrOf: (in category 'type declaration') -----
+ checkedFloatPtrOf: oop
+ "Originally implemented (ar) in FFTPlugin, also found in KlattPlugin, copied here for testing"
+ "Return the first indexable word of oop which is assumed to be variableWordSubclass"
+ <returnTypeC:'float *'>
+ interpreterProxy success: (interpreterProxy isWords: oop).
+ interpreterProxy failed ifTrue:[^0].
+ ^self cCoerce: (interpreterProxy firstIndexableField: oop) to:'float *'!
Item was added:
+ ----- Method: SlangTestSupportPlugin>>checkedShortPtrOf: (in category 'type declaration') -----
+ checkedShortPtrOf: oop
+ "Originally implemented in FFTPlugin, also found in KlattPlugin, copied here for testing"
+ "Return the first indexable word of oop which is assumed to be variableWordSubclass"
+ <returnTypeC: 'short *'>
+ interpreterProxy success: (interpreterProxy isWords: oop).
+ interpreterProxy failed ifTrue:[^0].
+ ^self cCoerce: (interpreterProxy firstIndexableField: oop) to:'short *'!
Item was added:
+ ----- Method: SlangTestSupportPlugin>>testTwoInlinedCCoerceInOneMethod (in category 'type declaration') -----
+ testTwoInlinedCCoerceInOneMethod
+ "Pattern appearing in KlattPlugin>>loadFrom:
+ Translated C code should have one type cast (not two)"
+
+ <export: true>
+ shortPointer := self checkedShortPtrOf: 789..
+ floatPointer := self checkedFloatPtrOf: 12345..
+ !
Item was changed:
----- Method: VMMaker class>>versionString (in category 'version testing') -----
versionString
"VMMaker versionString"
+ ^'4.20.3'!
- ^'4.20.2'!
Marcel Taeumel uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-mt.3285.mcz
==================== Summary ====================
Name: VMMaker.oscog-mt.3285
Author: mt
Time: 30 December 2022, 5:38:46.225292 pm
UUID: a32030a9-258c-fb43-b556-5950b2f34c9e
Ancestors: VMMaker.oscog-eem.3284
Fix typo in #long64At:put: to use correct primitive.
Some clean-up in *VMMaker-accessing helper methods in ByteArray.
In the long term, client code should switch to *FFI-Kernel-accessing. #int32At:(put:), #int64At:(put:), ...
=============== Diff against VMMaker.oscog-eem.3284 ===============
Item was changed:
----- Method: ByteArray>>long32At: (in category '*VMMaker-accessing') -----
long32At: byteIndex
+ "Answer a 32-bit integer in platform native order starting at the given byte offset."
- "Store a 32bit signed integer starting at the given byte offset"
<primitive: #primitiveSignedInt32At module: #SqueakFFIPrims error: ec>
^self integerAt: byteIndex size: 4 signed: true!
Item was added:
+ ----- Method: ByteArray>>long32At:put: (in category '*VMMaker-accessing') -----
+ long32At: byteIndex put: aValue
+ "Store a 32bit signed integer starting at the given byte offset"
+ <primitive: #primitiveSignedInt32AtPut module: #SqueakFFIPrims error: ec>
+ ^self integerAt: byteIndex put: aValue size: 4 signed: true!
Item was changed:
----- Method: ByteArray>>long64At: (in category '*VMMaker-accessing') -----
+ long64At: byteIndex
+ "Answer a 64-bit integer in platform native order starting at the given byte offset."
- long64At: index
- "Answer a 64-bit integer in platform native order."
<primitive: #primitiveSignedInt64At module: #SqueakFFIPrims error: ec>
+ ^self integerAt: byteIndex size: 8 signed: true!
- ^self integerAt: index size: 8 signed: true!
Item was changed:
----- Method: ByteArray>>long64At:put: (in category '*VMMaker-accessing') -----
long64At: index put: value
+ "Store a 64-bit integer in platform native order starting at the given byte offset."
+ <primitive: #primitiveSignedInt64AtPut module: #SqueakFFIPrims error: ec>
- "I store 64-bit integers in platform native order."
- <primitive: #primitiveSignedInt648At module: #SqueakFFIPrims error: ec>
^self integerAt: index put: value size: 8 signed: true!
Item was changed:
----- Method: ByteArray>>longAt: (in category '*VMMaker-accessing') -----
longAt: byteIndex
+ "Answer a 32-bit integer in platform native order starting at the given byte offset."
- "Store a 32-bit signed integer starting at the given byte offset"
<primitive: #primitiveSignedInt32At module: #SqueakFFIPrims error: ec>
^self integerAt: byteIndex size: 4 signed: true!
Item was changed:
----- Method: ByteArray>>longAt:put: (in category '*VMMaker-accessing') -----
longAt: byteIndex put: aValue
"Store a 32bit signed integer starting at the given byte offset"
+ <primitive: #primitiveSignedInt32AtPut module: #SqueakFFIPrims error: ec>
^self integerAt: byteIndex put: aValue size: 4 signed: true!
Item was changed:
----- Method: ByteArray>>unsignedLong64At: (in category '*VMMaker-accessing') -----
unsignedLong64At: byteOffset
+ "Answer a 64-bit unsigned integer in platform native order starting at the given byte offset."
- "Answer a 64-bit integer in platform native order."
<primitive: #primitiveUnsignedInt64At module: #SqueakFFIPrims error: ec>
^self integerAt: byteOffset size: 8 signed: false!
Item was changed:
----- Method: ByteArray>>unsignedLong64At:put: (in category '*VMMaker-accessing') -----
unsignedLong64At: byteOffset put: value
+ "Store a 64-bit unsigned integer in platform native order starting at the given byte offset."
+ <primitive: #primitiveUnsignedInt64AtPut module: #SqueakFFIPrims error: ec>
- "I store 64-bit integers in Smalltalk (little-endian) order."
^self integerAt: byteOffset put: value size: 8 signed: false!