-
Notifications
You must be signed in to change notification settings - Fork 67
/
BalloonArray.class.st
114 lines (97 loc) · 3.01 KB
/
BalloonArray.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"
BalloonArray keeps a shadow copy of its raw memory data in a Smalltalk array. This allows support for C's inhomogeneous access, returning floats where Floats were stored, and negative ints where they were stored. This ruse only works, of course where we have control over all the access.
"
Class {
#name : #BalloonArray,
#superclass : #CArray,
#instVars : [
'simArray',
'simOffset'
],
#category : #'VMMaker-InterpreterSimulation'
}
{ #category : #'pointer arithmetic' }
BalloonArray >> += increment [
super += increment.
simOffset := simOffset + (increment / unitSize)
]
{ #category : #'pointer arithmetic' }
BalloonArray >> -= increment [
super -= increment.
simOffset := simOffset - (increment / unitSize)
]
{ #category : #'memory access' }
BalloonArray >> at: index [
| value |
value := simArray at: index + simOffset.
"Debug only..."
value ifNil:
[self error: 'attempt to read an uninitialized field'.
^ super at: index "Maybe it was set in Squeak. Return the raw value"].
(self bitsOf: value) ~= (super at: index) ifTrue:
[self error: 'inconsistent values: ', (self bitsOf: value) printString, ' vs ', (super at: index) printString].
^value
]
{ #category : #'memory access' }
BalloonArray >> at: index put: value [
super at: index put: (self bitsOf: value).
^ simArray at: index + simOffset put: value.
]
{ #category : #'memory access' }
BalloonArray >> bitsOf: value [
"Convert pos and neg ints and floats to 32-bit representations expected by C"
value isInteger ifTrue:
[value >= 0 ifTrue: [^ value].
^ value + 16r80000000 + 16r80000000].
value isFloat ifTrue:
[^ value asIEEE32BitWord].
self error: 'unexpected value for 32 bits'.
^ 0
]
{ #category : #'memory access' }
BalloonArray >> floatAt: index [
| value |
value := self at: index.
value isFloat ifFalse:
[value = 0 ifTrue: [^ 0.0].
self error: 'non-float was stored'.
^ Float fromIEEE32Bit: value].
^ value
]
{ #category : #'memory access' }
BalloonArray >> floatAt: index put: value [
value isFloat
ifFalse: [self error: 'inconsistent values'].
^ self at: index put: value
]
{ #category : #'memory access' }
BalloonArray >> intAt: index [
| value |
value := self at: index.
value isInteger
ifFalse: [self error: 'inconsistent values'].
^ value
]
{ #category : #'memory access' }
BalloonArray >> intAt: index put: value [
value isInteger
ifFalse: [self error: 'inconsistent values'].
^ self at: index put: value
]
{ #category : #'memory access' }
BalloonArray >> setSimArray: anArray [
simArray := anArray.
"Now sync the contents of the simArray with the actual work buffer.
The issue here is that whether an element is an in teger or a float depends
on how the BalloonArrayPlugin accesses the workBuffer; hence we look at
the existing values in simArray to find that interpretation."
simOffset ifNil:
[simOffset := 1].
0 to: anArray size - 1 do:
[:i|
anArray
at: i + simOffset
put: ((anArray at: i + simOffset) isFloat
ifTrue: [(Float fromIEEE32Bit: (super at: i))]
ifFalse: [super at: i])]
]