Writes from pointer on stack
zWCDBL => {
DoCountedWrite: PROC [refVal: DValue, refLoc: LPtr2] = TRUSTED MACHINE CODE {zWCDBL, 0};
alpha: CARDINAL = RI.NextOpByte[m];
refLoc: LPtr2 ← RI.LPtr2V[RI.Pop2[m]] + alpha;
refVal: DValue ← RI.Pop2[m];
RefCount: TYPE = MACHINE DEPENDENT RECORD [filler (0:0..8): [0..777B], count (0:9..15): [0..177B]];
oldRef: LONG POINTER TO RefCount;
oldCount: NAT;
record various memory references
oldRef ← LOOPHOLE[RI.LPtr1V[RI.ReadDouble[m, refLoc]]];
IF oldRef #
NIL
THEN {
RI.ReadAtAddress[m, oldRef-2];
oldCount ← (oldRef-2).count;
IF oldCount = 2 (low bit is overflow, so this means decr will be to 0).
write to the ZCT (the microcode may be the only one that knows where)
RI.WriteAtAddress[m, oldRef-2];
};
RI.DoubleWriteAtAddress[m, refLoc];
RI.ReadAtAddress[m, RI.LPtr1V[refVal]-2]; -- increment ref count
RI.WriteAtAddress[m, RI.LPtr1V[refVal]-2];
DoCountedWrite[refVal: refVal, refLoc: refLoc];
};
zICDBL => {
DoCountedInitialize: PROC [refVal: DValue, refLoc: LPtr2] = TRUSTED MACHINE CODE {zICDBL, 0};
alpha: CARDINAL = RI.NextOpByte[m];
refLoc: LPtr2 ← RI.LPtr2V[RI.Pop2[m]] + alpha;
refVal: DValue ← RI.Pop2[m];
record various memory references
RI.DoubleWriteAtAddress[m, refLoc];
RI.ReadAtAddress[m, RI.LPtr1V[refVal]-2]; -- increment ref count
RI.WriteAtAddress[m, RI.LPtr1V[refVal]-2];
DoCountedInitialize[refVal: refVal, refLoc: refLoc];
};
zW0, zW1, zW2 => {
n: CARDINAL ← op - zW0;
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.Write[m, LONG[p+n], v]};
zWB => {
n: CARDINAL ← RI.NextOpByte[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.Write[m, LONG[p+n], v]};
zWBL => {
n: CARDINAL ← RI.NextOpByte[m];
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
v: Value ← RI.Pop[m];
RI.Write[m, p+n, v]};
zWD0 => {
n: CARDINAL ← 0;
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, LONG[p+n], v]};
zWDB => {
n: CARDINAL ← RI.NextOpByte[m];
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, LONG[p+n], v]};
zWDBL => {
n: CARDINAL ← RI.NextOpByte[m];
p: LPtr2 ← RI.LPtr2V[RI.Pop2[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, p+n, v]};
zWF => {
n: CARDINAL ← RI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.WriteField[m, LONG[p+n], fd, v]};
zWFL => {
n: CARDINAL ← RI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
v: Value ← RI.Pop[m];
RI.WriteField[m, p+n, fd, v]};