Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.1415.mcz
==================== Summary ====================
Name: Kernel-ul.1415
Author: ul
Time: 21 September 2021, 12:15:33.429302 am
UUID: 475b52e5-ca1e-4e9a-bf3f-bdc55f143e01
Ancestors: Kernel-eem.1414
MethodDictionary has to reimplement some inherited methods: #add, #at:ifPresent:ifAbsentPut: and #replace:
=============== Diff against Kernel-eem.1414 ===============
Item was added:
+ ----- Method: MethodDictionary>>add: (in category 'adding') -----
+ add: anAssociation
+
+ self at: anAssociation key put: anAssociation value.
+ ^anAssociation!
Item was added:
+ ----- Method: MethodDictionary>>at:ifPresent:ifAbsentPut: (in category 'accessing') -----
+ at: key ifPresent: oneArgBlock ifAbsentPut: absentBlock
+ "Lookup the given key in the receiver. If it is present, answer the value of
+ evaluating oneArgBlock with the value associated with the key. Otherwise
+ add the value of absentBlock under the key, and answer that value."
+
+ | index value |
+ index := self scanFor: key.
+ (array at: index) ifNotNil: [ :element | ^oneArgBlock value: element value].
+ value := absentBlock value.
+ self
+ basicAt: index put: key;
+ atNewIndex: index put: value.
+ ^value!
Item was added:
+ ----- Method: MethodDictionary>>replace: (in category 'enumeration') -----
+ replace: aBlock
+ "Destructively replace the values in this Dictionary by applying aBlock, keeping the same keys."
+
+ tally = 0 ifTrue: [ ^self].
+ 1 to: array size do: [ :index |
+ (array at: index) ifNotNil: [ :element |
+ array at: index put: (aBlock value: element) ] ]!
Levente Uzonyi uploaded a new version of WebClient-Core to project The Trunk:
http://source.squeak.org/trunk/WebClient-Core-ul.128.mcz
==================== Summary ====================
Name: WebClient-Core-ul.128
Author: ul
Time: 21 September 2021, 2:16:18.204886 pm
UUID: 2ea71dca-a72d-4724-b8a2-98b1ab2e8e8a
Ancestors: WebClient-Core-dtl.127
- added missing vertical bars to empty blocks
=============== Diff against WebClient-Core-dtl.127 ===============
Item was changed:
----- Method: WebClient>>httpDelete: (in category 'methods') -----
httpDelete: urlString
"Sends an DELETE request"
+ ^self httpDelete: urlString do:[:req|]
- ^self httpDelete: urlString do:[:req]
!
Item was changed:
----- Method: WebClient>>httpGet: (in category 'methods') -----
httpGet: urlString
"GET the response from the given url"
"(WebClient httpGet: 'http://www.squeak.org') content"
+ ^self httpGet: urlString do:[:req|]
- ^self httpGet: urlString do:[:req]
!
Item was changed:
----- Method: WebClient>>httpHead: (in category 'methods') -----
httpHead: urlString
"Sends a HEAD request"
+ ^self httpHead: urlString do:[:req|]
- ^self httpHead: urlString do:[:req]
!
Item was changed:
----- Method: WebClient>>httpOptions: (in category 'methods') -----
httpOptions: urlString
"Sends an OPTIONS request"
+ ^self httpOptions: urlString do:[:req|]
- ^self httpOptions: urlString do:[:req]
!
Item was changed:
----- Method: WebClient>>httpPost:content:type: (in category 'methods') -----
httpPost: urlString content: postData type: contentType
"POST the data to the given url"
+ ^self httpPost: urlString content: postData type: contentType do:[:req|]!
- ^self httpPost: urlString content: postData type: contentType do:[:req]!
Item was changed:
----- Method: WebClient>>httpPostChunked:content:type: (in category 'methods') -----
httpPostChunked: urlString content: chunkBlock type: contentType
"POST the data to the given url using chunked transfer-encoding.
The chunkBlock takes a request and can be fed using #nextChunkPut:
until all the data has been sent.
Chunked encoding can be used for long-lasting connections to a server,
but care must be taken to ensure that the client isn't running afoul of
the server expecting to read the full response (i.e., you should use this
only if you have control over both ends).
However, it is a great way to send output from commands that take awhile
and other time-consuming operations if authentication has been handled."
+ ^self httpPostChunked: urlString content: chunkBlock type: contentType do: [:req|]!
- ^self httpPostChunked: urlString content: chunkBlock type: contentType do: [:req]!
Item was changed:
----- Method: WebClient>>httpPut:content:type: (in category 'methods') -----
httpPut: urlString content: postData type: contentType
"PUT the data to the given url"
+ ^self httpPut: urlString content: postData type: contentType do:[:req|]!
- ^self httpPut: urlString content: postData type: contentType do:[:req]!
Item was changed:
----- Method: WebClient>>httpTrace: (in category 'methods') -----
httpTrace: urlString
"Sends a TRACE request"
+ ^self httpTrace: urlString do:[:req|]
- ^self httpTrace: urlString do:[:req]
!
Item was changed:
----- Method: WebRequest>>send200Response:contentType: (in category 'responses') -----
send200Response: aString contentType: contentType
"Send a 200 OK response"
+ ^self send200Response: aString contentType: contentType do:[:resp|]!
- ^self send200Response: aString contentType: contentType do:[:resp]!
Item was changed:
----- Method: WebRequest>>send301Response: (in category 'responses') -----
send301Response: location
"Send a 301 permanent redirect response"
+ ^self send301Response: location do:[:resp|].!
- ^self send301Response: location do:[:resp].!
Item was changed:
----- Method: WebRequest>>send302Response: (in category 'responses') -----
send302Response: location
"Send a 302 temporary redirect response"
+ ^self send302Response: location do:[:resp|].!
- ^self send302Response: location do:[:resp].!
Item was changed:
----- Method: WebRequest>>send3xxResponse:code: (in category 'responses') -----
send3xxResponse: location code: statusCode
"Send a 3xx redirect response"
+ ^self send3xxResponse: location code: statusCode do:[:resp|].!
- ^self send3xxResponse: location code: statusCode do:[:resp].!
Item was changed:
----- Method: WebRequest>>sendResponse:chunked: (in category 'responses') -----
sendResponse: code chunked: chunkBlock
"Send a chunked response"
+ ^self sendResponse: code chunked: chunkBlock do:[:resp|]!
- ^self sendResponse: code chunked: chunkBlock do:[:resp]!
Item was changed:
----- Method: WebRequest>>stream200Response:size:type: (in category 'responses') -----
stream200Response: aStream size: streamSize type: contentType
"Stream a 200 OK response"
+ ^self stream200Response: aStream size: streamSize type: contentType do:[:resp|].!
- ^self stream200Response: aStream size: streamSize type: contentType do:[:resp].!
Item was changed:
----- Method: WebServer>>handleConnectionFrom: (in category 'handling') -----
handleConnectionFrom: aSocket
"Synchronously handle an incoming socket connection."
| stream request |
"Give the process a pretty name"
Processor activeProcess name: (String streamContents:[:s|
aSocket remoteAddress do:[:b| s print: b] separatedBy:[s nextPut: $.].
s nextPut: $:; print: aSocket remotePort.
s nextPutAll: ' - ', self class name, ' request handler'.
]).
"Read the request from the socket, and dispatch it.
Since we've been forked already it's okay to block."
[
certName ifNil:["Regular request"
stream := SocketStream on: aSocket.
] ifNotNil:["SSL/TLS"
| ssl |
ssl := Smalltalk at: #SqueakSSL ifAbsent:[self error: 'SqueakSSL not installed'].
stream := ssl secureSocketStream on: aSocket.
[stream sslAccept: certName] on: Error do:[^stream destroy].
].
[aSocket isConnected] whileTrue:[
"Read the next request from the connection. If the connection is closed,
or if a network error occurs, or the read times out, just close the connection
without further ado (rather than logging an error). Any other error resulting
from parsing the input is treated as a 400 bad request."
stream peek ifNil:[^aSocket destroy].
request := self newRequest.
[request readFrom: stream] on: Error do:[:ex|
(ex isKindOf: NetworkError) ifFalse:[
+ [request send400Response] on: Error do:[:ignore|].
- [request send400Response] on: Error do:[:ignore].
].
^aSocket destroy].
self dispatchRequest: request.
].
] on: Error do:[:ex|
(ex isKindOf: NetworkError) ifFalse:[
self log: 'Error in request handling: ', ex description.
self log: (self errorReportFor: ex).
].
].!
Eliot Miranda uploaded a new version of SystemReporter to project The Trunk:
http://source.squeak.org/trunk/SystemReporter-eem.52.mcz
==================== Summary ====================
Name: SystemReporter-eem.52
Author: eem
Time: 20 September 2021, 5:59:45.008905 pm
UUID: 55eed9c6-65db-4b42-94de-dc83820e3aad
Ancestors: SystemReporter-eem.51
Add reporting of the VM's "can catch exceptions in FFI calls" flag.
=============== Diff against SystemReporter-eem.51 ===============
Item was changed:
----- Method: SystemReporter>>reportVMParameters: (in category 'reporting') -----
reportVMParameters: aStream
| vmParameters isStack isCog isSpur |
self header: 'Virtual Machine Parameters' on: aStream.
vmParameters := Smalltalk vm getVMParameters.
isStack := (vmParameters at: 42 ifAbsent: [0]) ~= 0. "42 = number of stack pages available"
isCog := isStack and: [(vmParameters at: 46) ~= 0]. "46 is machine code zone size"
isSpur := isStack and: [(vmParameters at: 41) anyMask: 2r10000]. "41 is imageFormatVersion for the VM; bit 16 is the Spur bit"
(isSpur
ifFalse:
[#( 1 'size of old space'
2 'size of young+old space'
3 'size of memory'
4 'allocationCount'
5 'allocations between GCs'
6 'survivor count tenuring threshold')]
ifTrue:
[#( 1 'size of old space'
2 'used bytes in new space (used eden + used past space)'
3 'size of heap')]),
#( 7 'full GCs since startup'
8 'total milliseconds in full GCs since startup'),
(isSpur
ifFalse: [#( 9 'incremental GCs since startup'
10 'total milliseconds in incremental GCs since startup'
11 'tenures of surving objects since startup'),
{12 to: 19. 'specific to the translating VM'}]
ifTrue: [#( 9 'scavenging GCs since startup'
10 'total milliseconds in scavenging GCs since startup'
11 'tenures of surving objects since startup'
12 'event trace mask (for debugging input events)'
13 'VM ticker start microseconds (Croquet/QwaqVM)'
14 'VM ticker count (Croquet/QwaqVM)'
15 'VM ticker call count (Croquet/QwaqVM)'
16 'total microseconds in idle since startup'
17 'proportion of code zone available for use (Sista VMs only; read-write)'
18 'total milliseconds in full GC compaction since startup (a portion of parameter 8)'
19 'scavenge threshold; the effective size of eden')]),
#( 20 'utc microseconds at startup (if non-zero)'
21 'root/remembered table size (occupancy)'
22 'root/remembered table overflows since startup'
23 'bytes of extra memory to reserve for VM buffers, plugins, etc.'
24 'free memory threshold above which object memory will be shrunk'
25 'memory headroom when growing object memory'),
(isStack
ifFalse:
[#( 26 'interruptChecksEveryNms - force an ioProcessEvents every N milliseconds, in case the image is not calling getNextEvent often')]
ifTrue:
[#( 26 'heartbeat period (ms; see #58)')]),
(isSpur
ifFalse:
[#( 27 'number of times mark loop iterated for current IGC/FGC includes ALL marking'
28 'number of times sweep loop iterated for current IGC/FGC'
29 'number of times make forward loop iterated for current IGC/FGC'
30 'number of times compact move loop iterated for current IGC/FGC')]
ifTrue: [#()]),
#( 31 'number of grow memory requests'
32 'number of shrink memory requests'),
(isSpur
ifFalse:
[#( 33 'number of root table entries used for current IGC/FGC'
34 'number of allocations done before current IGC/FGC'
35 'number of survivor objects after current IGC/FGC'
36 'millisecond clock when current IGC/FGC completed'
37 'number of marked objects for Roots of the world, not including Root Table entries for current IGC/FGC'
38 'milliseconds taken by current IGC'
39 'Number of finalization signals for Weak Objects pending when current IGC/FGC completed')]
ifTrue:
[#( 33 'number of root table entries at last scavenge'
35 'number of survivor objects at last scavenge (if non-zero)'
36 'millisecond clock when current scavenge completed'
38 'milliseconds taken by current scavenge'
39 'Number of finalization signals for Weak Objects pending when current SGC/FGC completed')]),
#( 40 'VM word size - 4 or 8'),
(isStack
ifTrue:
[#(
41 'imageFormatVersion for the VM'
42 'number of stack pages available'
43 'desired number of stack pages (stored in image file header, max 65535)'
44 'size of eden, in bytes'
45 'desired size of eden, in bytes (stored in image file header)'
46 'machine code zone size, in bytes (0 in Stack VM)'
47 'desired machine code zone size (0 => default 1Mb to 2Mb depending on processor)'),
{ 48. 'Persistent image header flags\ bit 0: implies Process has threadId as its 4th inst var\ bit 1: if set, methods that are interpreted will have the flag bit set in their header\ bit 2: if set, implies preempting a process does not put it to the back of its run queue\ bit 3: if set, implies the GUI should run on the first thread and event queues should not be accessed from other threads\ bit 4: if set, implies the new finalization scheme where WeakArrays are queued\ bit 5: if set, implies wheel events will be delivered as such and not mapped to arrow key events\ bit 6: if set, implies arithmetic primitives will fail if given arguments of different types (float vs int)\ bit 7: if set, causes times delivered from file primitives to be in UTC rather than local time.' withCRs },
#( 49 'max size the image promises to grow the external semaphore table to'),
(isSpur
ifFalse:
[{ 50 to: 51. 'reserved for VM parameters that persist in the image (such as size of eden above)'.
52 to: 56. 'specific to Spur' }]
ifTrue:
[{ 50 to: 51. 'reserved for VM parameters that persist in the image (such as size of eden above)' },
#( 52 'root/remembered table capacity'
53 'number of old space segments'
54 'total free old space'
55 'ratio of growth and image size at or above which a GC will be performed post scavenge')]),
#( 56 'number of process switches since startup'
57 'number of ioProcessEvents calls since startup'
58 'number of forceInterruptCheck calls since startup'
59 'number of check event calls since startup'
60 'number of stack page overflows since startup'
61 'number of stack page divorces since startup'
62 'compiled code compactions since startup'),
(isCog
ifFalse:
[#()]
ifTrue:
[#( 63 'total milliseconds in compiled code compactions since startup'
64 'the number of methods that currently have jitted machine-code')]),
+ { 65. 'Cog feature flags\ bit 0: set if the VM supports MULTIPLE_BYTECODE_SETS.\ bit 1: set if the VM supports read-only objects (IMMUTABILITY).\ bit 2: set if the VM has an ITIMER_HEARTBEAT\ bit 3: set if the VM supports cross-platform BIT_IDENTICAL_FLOATING_POINT arithmetic\ bit 4: set if the VM can catch exceptions in FFI calls and answer them as primitive failures' withCRs.
- { 65. 'Cog feature flags\ bit 0: set if the VM supports MULTIPLE_BYTECODE_SETS.\ bit 1: set if the VM supports read-only objects (IMMUTABILITY).\ bit 2: set if the VM has an ITIMER_HEARTBEAT\ bit 3: set if the VM supports cross-platform BIT_IDENTICAL_FLOATING_POINT arithmetic' withCRs.
66. 'the byte size of a stack page'.},
(isSpur
ifFalse:
[{ 67 to: 69. 'reserved for more Cog-related info' }]
ifTrue:
[#( 67 'the maximum allowed size of old space (if zero there is no limit)'
68 'the average number of live stack pages when scanned by scavenge/gc/become'
69 'the maximum number of live stack pages when scanned by scavenge/gc/become')]),
#( 70 'the vmProxyMajorVersion (the interpreterProxy VM_MAJOR_VERSION)'
71 'the vmProxyMinorVersion (the interpreterProxy VM_MINOR_VERSION)'),
(isSpur
ifFalse: [#()]
ifTrue:
[#( 72 'milliseconds spent marking since startup'
73 'reserved for more Spur-related info'
74 'reserved for more Spur-related info'
75 'do mixed arithmetic; if false binary arithmetic primitives will fail unless receiver and argument are of the same type')]),
(isCog
ifFalse: [#()]
ifTrue: [#(76 'minimum unused bytes of headroom on all stack pages')])]
ifFalse:
[#()])
pairsDo: [:idx :desc | | value values |
(idx isInteger ifTrue: [idx] ifFalse: [idx last]) <= vmParameters size ifTrue:
[aStream nextPut: $#.
idx isInteger
ifTrue:
[value := vmParameters at: idx.
aStream
print: idx; tab: (idx < 10 ifTrue: [2] ifFalse: [1]);
nextPutAll: ((value isInteger and: [idx ~= 41])
ifTrue: [(desc includesSubstring: 'bit 0:')
ifTrue: [value printStringBase: 2 nDigits: value highBit]
ifFalse: [value asStringWithCommas]]
ifFalse: [value printString])]
ifFalse:
[value := vmParameters at: idx first.
aStream print: idx first; next: 2 put: $.; print: idx last; tab.
values := idx collect: [:i| vmParameters at: i].
values asSet size = 1
ifTrue: [aStream print: value]
ifFalse: [values do: [:v| aStream print: v] separatedBy: [aStream nextPutAll: ', ']]].
aStream tab; nextPutAll: desc; cr]]!
Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1415.mcz
==================== Summary ====================
Name: Kernel-eem.1415
Author: eem
Time: 20 September 2021, 3:40:41.04035 pm
UUID: b3b62e4b-49b1-4463-93de-6c69109de02d
Ancestors: Kernel-eem.1414
An alternative fix to http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-September/21652…
c.f. Kernel-ul.1415
=============== Diff against Kernel-eem.1414 ===============
Item was added:
+ ----- Method: MethodDictionary>>add: (in category 'adding') -----
+ add: anAssociation
+
+ | index |
+ index := self scanFor: anAssociation key.
+ (array at: index)
+ ifNil: [ self atNewIndex: index put: anAssociation ]
+ ifNotNil: [ array at: index put: anAssociation value ].
+ ^anAssociation!
Item was changed:
----- Method: MethodDictionary>>at:put: (in category 'accessing') -----
at: key put: value
"Set the value at key to be value."
| index |
index := self scanFor: key.
(self basicAt: index)
ifNil: [
self
basicAt: index put: key;
+ atNewIndex: index putValue: value ]
- atNewIndex: index put: value ]
ifNotNil: [
(array at: index) flushCache.
array at: index put: value ].
^value!
Item was added:
+ ----- Method: MethodDictionary>>atNewIndex:put: (in category 'private') -----
+ atNewIndex: index put: anAssociation
+ "Override to deal with the internal organization of MethodDIctionaries
+ which, to suit the VM, do not use Associations."
+ self assert: anAssociation isVariableBinding.
+ self basicAt: index put: anAssociation key.
+ array at: index put: anAssociation value.
+ tally := tally + 1.
+ "Keep array at least 1/4 free for decent hash behavior"
+ array size * 3 < (tally * 4) ifTrue: [ self grow ]!
Item was added:
+ ----- Method: MethodDictionary>>atNewIndex:putValue: (in category 'private') -----
+ atNewIndex: index putValue: anObject
+ "Override to deal with the internal organization of MethodDIctionaries
+ which, to suit the VM, do not use Associations."
+ array at: index put: anObject.
+ tally := tally + 1.
+ "Keep array at least 1/4 free for decent hash behavior"
+ array size * 3 < (tally * 4) ifTrue: [ self grow ]!