Branch: refs/heads/Cog
Home: https://github.com/OpenSmalltalk/opensmalltalk-vm
Commit: 95e670d2b80c0a92d4de0b5d512b05db5a1f0dfb
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/95e670d2b80c0a92d4…
Author: Nicolas Cellier <nicolas.cellier(a)sirehna.com>
Date: 2022-08-23 (Tue, 23 Aug 2022)
Changed paths:
M platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c
Log Message:
-----------
Fix suspiscious check in Win32 socket plugin
>/usr/x86_64-w64-mingw32/sys-root/mingw/include/WinSock2.h:1029:88: note: passing argument to parameter 'optval' here
> WINSOCK_API_LINKAGE int WSAAPI setsockopt(SOCKET s,int level,int optname,const char *optval,int optlen);
> ^
>../../../platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c:1758:7: warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses]
> if (!opt == 0
> ^ ~~
Since opt is a pointer, !opt means (pointer is NULL)<br>
Then (!opt) == 0, means (pointer is NULL) is false, hence (pointer is not NULL).
So we would barf if pointer is not NULL?<br>
But on next line (reached if pointer IS NULL), we would dereference the pointer...<br>
Err, non-sensical.
I guess the intention was to BARF if pointer is NULL.
Commit: 6e3e0156dcb7b3f880292ce27a220354df186e68
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/6e3e0156dcb7b3f880…
Author: Nicolas Cellier <nicolas.cellier(a)sirehna.com>
Date: 2022-08-23 (Tue, 23 Aug 2022)
Changed paths:
M src/plugins/SocketPlugin/SocketPlugin.c
Log Message:
-----------
Fix some compiler warnings in generated code for SocketPlugin
See https://source.squeak.org/VMMaker/VMMaker.oscog-nice.3250.diff
Compare: https://github.com/OpenSmalltalk/opensmalltalk-vm/compare/1f1edcb426b4...6e…
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.3250.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.3250
Author: nice
Time: 23 August 2022, 3:35:17.389121 pm
UUID: e2df5590-0905-0b41-a0df-4909944ea81d
Ancestors: VMMaker.oscog-nice.3249
The security plugin shall not access the socket before it is set
See related compiler warnings in generated code:
./../../src/plugins/SocketPlugin/SocketPlugin.c:1435:62: warning: variable 's' is uninitialized when used here [-Wuninitialized]
okToListen = ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port);
../../../src/plugins/SocketPlugin/SocketPlugin.c:1487:62: warning: variable 's' is uninitialized when used here [-Wuninitialized]
okToListen = ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port);
More over, it shall not access the socket if it is not validated, hence we have to protect access with an interpreterProxy failed check.
Same for (IPV4) address.
=============== Diff against VMMaker.oscog-nice.3249 ===============
Item was changed:
----- Method: SocketPlugin>>primitiveSocket:connectTo:port: (in category 'primitives') -----
primitiveSocket: socket connectTo: address port: port
| addr s okToConnect |
<var: #s type: 'SocketPtr'>
self primitive: 'primitiveSocketConnectToPort' parameters: #(#Oop #ByteArray #SmallInteger ).
addr := self netAddressToInt: (self cCoerce: address to: 'unsigned char *').
"If the security plugin can be loaded, use it to check for permission.
If not, assume it's ok"
+ interpreterProxy failed ifFalse:
+ [sCCTPfn ~= 0 ifTrue:
+ [okToConnect := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCTPfn)(addr, port)'.
+ okToConnect ifFalse:
+ [^ interpreterProxy primitiveFail]]].
- sCCTPfn ~= 0 ifTrue:
- [okToConnect := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCTPfn)(addr, port)'.
- okToConnect ifFalse:
- [^ interpreterProxy primitiveFail]].
s := self socketValueOf: socket.
interpreterProxy failed ifFalse:
[self sqSocket: s ConnectTo: addr Port: port]!
Item was changed:
----- Method: SocketPlugin>>primitiveSocket:listenOnPort: (in category 'primitives') -----
primitiveSocket: socket listenOnPort: port
"one part of the wierdass dual prim primitiveSocketListenOnPort which
was warped by some demented evil person determined to twist the very
nature of reality"
| s okToListen |
<var: #s type: 'SocketPtr '>
self primitive: 'primitiveSocketListenOnPort' parameters: #(#Oop #SmallInteger ).
s := self socketValueOf: socket.
"If the security plugin can be loaded, use it to check for permission.
If not, assume it's ok"
- sCCLOPfn ~= 0 ifTrue:
- [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
- okToListen ifFalse:
- [^ interpreterProxy primitiveFail]].
interpreterProxy failed ifFalse:
+ [sCCLOPfn ~= 0 ifTrue:
+ [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
+ okToListen ifFalse:
+ [^ interpreterProxy primitiveFail]]].
+ interpreterProxy failed ifFalse:
[self sqSocket: s ListenOnPort: port]!
Item was changed:
----- Method: SocketPlugin>>primitiveSocket:listenOnPort:backlogSize: (in category 'primitives') -----
primitiveSocket: socket listenOnPort: port backlogSize: backlog
"second part of the wierdass dual prim primitiveSocketListenOnPort
which was warped by some demented evil person determined to twist the
very nature of reality"
| s okToListen |
<var: #s type: 'SocketPtr'>
self primitive: 'primitiveSocketListenOnPortBacklog' parameters: #(#Oop #SmallInteger #SmallInteger ).
"If the security plugin can be loaded, use it to check for permission.
If not, assume it's ok"
- sCCLOPfn ~= 0 ifTrue:
- [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
- okToListen ifFalse:
- [^interpreterProxy primitiveFail]].
s := self socketValueOf: socket.
interpreterProxy failed ifFalse:
+ [sCCLOPfn ~= 0 ifTrue:
+ [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
+ okToListen ifFalse:
+ [^interpreterProxy primitiveFail]]].
+ interpreterProxy failed ifFalse:
[self sqSocket: s ListenOnPort: port BacklogSize: backlog]!
Item was changed:
----- Method: SocketPlugin>>primitiveSocket:listenOnPort:backlogSize:interface: (in category 'primitives') -----
primitiveSocket: socket listenOnPort: port backlogSize: backlog interface: ifAddr
"Bind a socket to the given port and interface address with no more than backlog pending connections. The socket can be UDP, in which case the backlog should be specified as zero."
| s okToListen addr |
<var: #s type: #SocketPtr>
self primitive: 'primitiveSocketListenOnPortBacklogInterface' parameters: #(#Oop #SmallInteger #SmallInteger #ByteArray).
"If the security plugin can be loaded, use it to check for permission.
If not, assume it's ok"
- sCCLOPfn ~= 0 ifTrue:
- [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
- okToListen ifFalse:
- [^ interpreterProxy primitiveFail]].
s := self socketValueOf: socket.
+ interpreterProxy failed ifFalse:
+ [sCCLOPfn ~= 0 ifTrue:
+ [okToListen := self cCode: ' ((sqInt (*) (sqInt, sqInt)) sCCLOPfn)((sqInt)s, port)'.
+ okToListen ifFalse:
+ [^ interpreterProxy primitiveFail]]].
addr := self netAddressToInt: (self cCoerce: ifAddr to: #'unsigned char *').
interpreterProxy failed ifFalse:
[self sqSocket: s ListenOnPort: port BacklogSize: backlog Interface: addr]!
Yeah, I should really revisit my windows stuff from pre-2017
--
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/1f1edcb426b4a5a413…
You are receiving this because you are subscribed to this thread.
Message ID: <OpenSmalltalk/opensmalltalk-vm/commit/1f1edcb426b4a5a4136c98cf8ec97bdbef0759a6/81926659(a)github.com>
Branch: refs/heads/Cog
Home: https://github.com/OpenSmalltalk/opensmalltalk-vm
Commit: 27b340935bb5cd472517688c2c41a0913599bc37
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/27b340935bb5cd4725…
Author: Nicolas Cellier <nicolas.cellier(a)sirehna.com>
Date: 2022-08-23 (Tue, 23 Aug 2022)
Changed paths:
M platforms/win32/vm/sqWin32Window.c
Log Message:
-----------
Fix a warning: bzero function prototype missing
>../../../platforms/win32/vm/sqWin32Window.c:3221:4: warning: implicitly declaring library function 'bzero' with type 'void (void *, unsigned long long)' [-Wimplicit-function-declaration]
> bzero(traceFlags,1024);
> ^
>../../../platforms/win32/vm/sqWin32Window.c:3221:4: note: include the header <strings.h> or explicitly provide a declaration for 'bzero'
Commit: 1f1edcb426b4a5a4136c98cf8ec97bdbef0759a6
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/1f1edcb426b4a5a413…
Author: Nicolas Cellier <nicolas.cellier(a)sirehna.com>
Date: 2022-08-23 (Tue, 23 Aug 2022)
Changed paths:
M platforms/win32/vm/sqWin32Main.c
Log Message:
-----------
Fix the crashdump() function in win32 when not compiled with UNICODE
`wsprintf` is an hybrid function (a macro) for
- either `char*` version `wsprintfA`
- either `wchar_t*` version `wsprintfW`
depending on `#define UNICODE` or not define UNICODE...
If we use `wsprintf`, then we must use the `TEXT` macro for passing the format literal, and declare filename as `TCHAR*` which also is a macro.<br>
https://docs.microsoft.com/en-us/windows/win32/intl/windows-data-types-for-…
Here we explicitily use a `wchar_t*`filename and a `wchar_t*`literal format specification, so we want to bypass UNICODE macro and explicitely use `wsprintfW`
Compare: https://github.com/OpenSmalltalk/opensmalltalk-vm/compare/085c500c9e2b...1f…
The `BitBlt` blending rule `Form blendAlphaScaled` (`34`) doesn't blend the colors `0x00000000` (source; fully transparent) and `0xFFFFFFFF` (destination; white) correctly. The output is `0xFEFEFEFE` (slightly transparent white), whereas it should be `0xFFFFFFFF` (fully opaque white).
I think the problem lies in [the implementation](https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a45e… of `BitBltSimulation>>#alphaBlendScaled:with:`. When calculating the summand containing the `destinationWord`, a right bit shift by `8` is performed to normalize the result after multiplying with `unAlpha` (semantically a division by `256`). However, `unAlpha` is in the range `0x00` - `0xFF` and thus a division by `0xFF = 255` should be used instead. I think that the other bit shifts by `8` in the function are ok, as they are only used to extract or compose certain bytes and not to (semantically) divide a value by `256`.
This problem causes the described behavior, because the following computation is performed in each channel:
```((0xFF * 0xFF) >> 8) + 0x00 = 0xFE01 >> 8 = 0xFE```
A division by `0xFF` produces the expected result:
```((0xFF * 0xFF) / 0xFF) + 0x00 = 0xFE01 / 0xFF = 0xFF```
Code to reproduce:
```
| src dst |
src := (Form extent: 1 @ 1 depth: 1)
colorAt: 0 @ 0 put: Color black; "transparency is applied with the fillColor:"
yourself.
dst := (Form extent: 1 @ 1 depth: 32)
colorAt: 0 @ 0 put: Color white; "16rFFFFFFFF"
yourself.
dst
copyBits: (0 @ 0 corner: 1 @ 1)
from: src
at: 0 @ 0
clippingBox: (0 @ 0 corner: 1 @ 1)
rule: Form blendAlphaScaled
fillColor: Color transparent. "16r00000000"
(dst pixelValueAt: 0 @ 0) hex "16rFEFEFEFE"
```
Notes:
- I did not thoroughly test the proposed change, just calculated the result for the described case.
- I am no expert in writing high performance code, but a potential improved implementation may not use a division but rather a more optimized combination of `+`, `*` and `>>` to increase performance. A quick search on the internet shows some possible alternatives.
- I read in the contribution guidelines, that the VM is developed in Smalltalk and the C code is only generated from the Smalltalk code. I did not have the time to set up a VM image and just looked into the C code to find the problem. I hope the problem description still helps.
- The described behavior doesn't occur when blending two 32 bit `Form`s. I think this is due to `alphaSourceBlendBits32` being called in this case, which is optimized for edge cases with full or zero transparency and handles those correctly (it doesn't call `alphaBlendScaledwith`).
--
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/643
You are receiving this because you are subscribed to this thread.
Message ID: <OpenSmalltalk/opensmalltalk-vm/issues/643(a)github.com>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.3249.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.3249
Author: nice
Time: 22 August 2022, 8:02:32.900315 pm
UUID: 6b05b927-1aad-484c-b8df-95147a9ca6b4
Ancestors: VMMaker.oscog-nice.3248
...and fix missing bitAnd: for safely multiplexing the division by 255...
This is a better fix for https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/643.
Sorry for the noise
=============== Diff against VMMaker.oscog-nice.3248 ===============
Item was changed:
----- Method: BitBltSimulation>>alphaBlendConst:with:paintMode: (in category 'combination rules') -----
alphaBlendConst: sourceWord with: destinationWord paintMode: paintMode
"Blend sourceWord with destinationWord using a constant alpha.
Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.
The blend produced is alpha*source + (1.0-alpha)*dest, with the
computation being performed independently on each color component.
This function could eventually blend into any depth destination,
using the same color averaging and mapping as warpBlt.
paintMode = true means do nothing if the source pixel value is zero."
"This first implementation works with dest depths of 16 and 32 bits only.
Normal color mapping will allow sources of lower depths in this case,
and results can be mapped directly by truncation, so no extra color maps are needed.
To allow storing into any depth will require subsequent addition of two other
colormaps, as is the case with WarpBlt."
| pixMask destShifted sourceShifted destPixVal rgbMask sourcePixVal unAlpha result pixBlend shift blend maskShifted bitsPerColor blendAG blendRB |
<inline: false>
<returnTypeC: 'unsigned int'>
<var: 'sourceWord' type: #'unsigned int'>
<var: 'destinationWord' type: #'unsigned int'>
<var: 'blendRB' type: #'unsigned int'>
<var: 'blendAG' type: #'unsigned int'>
<var: 'result' type: #'unsigned int'>
<var: 'sourceAlpha' type: #'unsigned int'>
<var: 'unAlpha' type: #'unsigned int'>
<var: 'sourceShifted' type: #'unsigned int'>
<var: 'destShifted' type: #'unsigned int'>
<var: 'maskShifted' type: #'unsigned int'>
<var: 'pixMask' type: #'unsigned int'>
<var: 'rgbMask' type: #'unsigned int'>
<var: 'pixBlend' type: #'unsigned int'>
<var: 'blend' type: #'unsigned int'>
destDepth < 16 ifTrue: [^ destinationWord "no-op"].
unAlpha := 255 - sourceAlpha.
result := destinationWord.
destPPW = 1 ifTrue:["32bpp blends include alpha"
paintMode & (sourceWord = 0) "painting a transparent pixel" ifFalse:[
blendRB := ((sourceWord bitAnd: 16rFF00FF) * sourceAlpha) +
((destinationWord bitAnd: 16rFF00FF) * unAlpha) + 16r800080. "blend red and blue"
blendAG := ((sourceWord>> 8 bitAnd: 16rFF00FF) * sourceAlpha) +
((destinationWord>>8 bitAnd: 16rFF00FF) * unAlpha) + 16r800080. "blend alpha and green"
+ blendRB := (blendRB >> 8 bitAnd: 16rFF00FF) + blendRB >> 8 bitAnd: 16rFF00FF. "divide by 255"
+ blendAG := (blendAG >> 8 bitAnd: 16rFF00FF) + blendAG >> 8 bitAnd: 16rFF00FF.
- blendRB := blendRB >> 8 + blendRB >> 8 bitAnd: 16rFF00FF. "divide by 255"
- blendAG := blendAG >> 8 + blendAG >> 8 bitAnd: 16rFF00FF.
result := blendRB bitOr: blendAG<<8.
].
] ifFalse:[
pixMask := maskTable at: destDepth.
bitsPerColor := 5.
rgbMask := 16r1F.
maskShifted := destMask.
destShifted := destinationWord.
sourceShifted := sourceWord.
1 to: destPPW do:[:j |
sourcePixVal := sourceShifted bitAnd: pixMask.
((maskShifted bitAnd: pixMask) = 0 "no effect if outside of dest rectangle"
or: [paintMode & (sourcePixVal = 0) "or painting a transparent pixel"])
ifFalse:
[destPixVal := destShifted bitAnd: pixMask.
pixBlend := 0.
1 to: 3 do:
[:i | shift := (i-1)*bitsPerColor.
blend := (((sourcePixVal>>shift bitAnd: rgbMask) * sourceAlpha)
+ ((destPixVal>>shift bitAnd: rgbMask) * unAlpha))
+ 128. "+128 for rounding"
blend := blend >> 8 + blend >> 8 bitAnd: rgbMask. "divide by 255"
pixBlend := pixBlend bitOr: blend<<shift].
result := (result bitAnd: (pixMask << (j-1*16)) bitInvert32)
bitOr: pixBlend << (j-1*16)].
maskShifted := maskShifted >> destDepth.
sourceShifted := sourceShifted >> destDepth.
destShifted := destShifted >> destDepth].
].
^ result
!
Item was changed:
----- Method: BitBltSimulation>>alphaBlendScaled:with: (in category 'combination rules') -----
alphaBlendScaled: sourceWord with: destinationWord
"Blend sourceWord with destinationWord using the alpha value from sourceWord.
Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.
In contrast to alphaBlend:with: the color produced is
srcColor + (1-srcAlpha) * dstColor
e.g., it is assumed that the source color is already scaled."
<returnTypeC: #'unsigned int'>
<inline: false> "Do NOT inline this into optimized loops"
| unAlpha rb ag |
<var: 'sourceWord' type: #'unsigned int'>
<var: 'destinationWord' type: #'unsigned int'>
<var: 'rb' type: #'unsigned int'>
<var: 'ag' type: #'unsigned int'>
<var: 'unAlpha' type: #'unsigned int'>
unAlpha := 255 - (sourceWord >> 24). "High 8 bits of source pixel is source opacity (ARGB format)"
rb := (destinationWord bitAnd: 16rFF00FF) * unAlpha + 16r800080. "add 16r80 for rounding division to nearest byte"
- rb := rb >> 8 + rb >> 8. "divide by 255"
- rb := (rb bitAnd: 16rFF00FF) + (sourceWord bitAnd: 16rFF00FF). "blend red and blue components"
ag := (destinationWord >> 8 bitAnd: 16rFF00FF) * unAlpha + 16r800080. "add 16r80 for rounding division to nearest byte"
+ rb := (rb >> 8 bitAnd: 16rFF00FF) + rb >> 8. "divide by 255"
+ ag := (ag >> 8 bitAnd: 16rFF00FF) + ag >> 8. "divide by 255"
+ rb := (rb bitAnd: 16rFF00FF) + (sourceWord bitAnd: 16rFF00FF). "blend red and blue components"
- ag := ag >> 8 + ag >> 8. "divide by 255"
ag := (ag bitAnd: 16rFF00FF) + (sourceWord >> 8 bitAnd: 16rFF00FF). "blend alpha and green components"
rb := (rb bitAnd: 16rFF00FF) bitOr: (rb bitAnd: 16r01000100) * 16rFF >> 8. "saturate red and blue components if there is a carry"
ag := (ag bitAnd: 16rFF00FF) << 8 bitOr: (ag bitAnd: 16r01000100) * 16rFF. "saturate alpha and green components if there is a carry"
^ag bitOr: rb "recompose"!
Branch: refs/heads/Cog
Home: https://github.com/OpenSmalltalk/opensmalltalk-vm
Commit: 1eb5808a3ca25d241717f05cbc244e75a0b8848e
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/1eb5808a3ca25d2417…
Author: Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com>
Date: 2022-08-22 (Mon, 22 Aug 2022)
Changed paths:
M src/plugins/BitBltPlugin/BitBltPlugin.c
M src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
M src/plugins/SqueakFFIPrims/IA32FFIPlugin.c
M src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c
M src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c
Log Message:
-----------
Fix Issue 643 via VMMaker.oscog-nice.3248
Also re-generate those FFI plugin flavours missing the isFloatAtomic() function.<br>
This function is necessary because used in assertions.<br>
In fast mode, the assertions are skipped, so the fast VM did compile, but debug and assert variants would not...