Skip to content

Commit caf42d2

Browse files
authored
Refactor memory ranges (#314)
* Refactor memory ranges * fix type * remove comments * change comment
1 parent 8c9ab93 commit caf42d2

File tree

3 files changed

+136
-72
lines changed

3 files changed

+136
-72
lines changed

src/components/MemoryPreview/MemoryInfinite.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const ITEM_SIZE = 24;
2424
const PAGE_SIZE = 4096;
2525
const BG_COLOR = "#22cccc";
2626

27-
const MemoryCell = ({
27+
export const MemoryCell = ({
2828
value,
2929
address,
3030
selectedAddress,

src/components/MemoryPreview/MemoryRanges.tsx

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import { Label } from "@/components/ui/label";
77
import { Edit3, Check, HelpCircle, ArrowUp, ArrowDown, Trash } from "lucide-react";
88
import { loadMemoryRangeAllWorkers, selectMemoryRangesForFirstWorker } from "@/store/workers/workersSlice";
99
import { useAppDispatch, useAppSelector } from "@/store/hooks";
10-
import { AddressInput, MemoryRow } from "./MemoryInfinite";
10+
import { AddressInput, MemoryCell } from "./MemoryInfinite";
1111
import { MEMORY_SPLIT_STEP } from "@/store/utils";
12-
import { addressFormatter, FindMemoryForWorkerType, getMemoryInterpretations } from "./utils";
12+
import { FindMemoryForWorkerType, getMemoryInterpretations } from "./utils";
1313
import { NumeralSystemContext } from "@/context/NumeralSystemContext";
1414
import classNames from "classnames";
15+
import { valueToNumeralSystem } from "../Instructions/utils";
1516

1617
const findMemoryForWorkerRange = (rangeAddress: number): FindMemoryForWorkerType => {
1718
return (worker, address) => {
@@ -138,20 +139,15 @@ function MemoryRangeRow({
138139
};
139140

140141
const isInputsVisible = isEditing || isLast;
141-
const lastAddressLength = addressFormatter(
142-
matchingRange?.startAddress || 0 + (matchingRange?.length || 0),
143-
numeralSystem,
144-
).length;
145-
146-
const flatData = new Uint8Array(rowData.flatMap((chunk) => chunk));
147-
const interpretResult = getMemoryInterpretations(flatData, numeralSystem);
142+
const flatData = rowData.flatMap((chunk) => chunk);
143+
const interpretResult = getMemoryInterpretations(new Uint8Array(flatData), numeralSystem);
148144

149145
return (
150-
<Card className="p-3 rounded-none">
146+
<Card className="p-3 border-0 border-b-2 rounded-none">
151147
<div className="flex items-center gap-3">
152148
{!isInputsVisible ? (
153149
<span className="font-mono">
154-
{start}...+{length}
150+
{valueToNumeralSystem(start, numeralSystem)}...+{valueToNumeralSystem(length, numeralSystem)}
155151
</span>
156152
) : (
157153
<>
@@ -164,7 +160,7 @@ function MemoryRangeRow({
164160
value={draftStart.toString()}
165161
/>
166162
</div>
167-
<div className="grid gap-1 max-w-[55px]">
163+
<div className="grid gap-1 max-w-[65px]">
168164
<Label htmlFor={`length-${id}`}>Length</Label>
169165
<LengthInput
170166
id={`length-${id}`}
@@ -216,19 +212,17 @@ function MemoryRangeRow({
216212

217213
<div className="mt-2 text-sm font-mono">
218214
<div style={{ maxHeight: "100px", overflowY: "auto" }}>
219-
{rowData.length === 0 ? (
215+
{flatData.length === 0 ? (
220216
<div>(no data)</div>
221217
) : (
222-
rowData.map((chunkBytes, idx) => (
223-
<div key={idx} className="flex items-start">
224-
<MemoryRow
225-
address={draftStart + idx * MEMORY_SPLIT_STEP}
226-
bytes={chunkBytes}
227-
selectedAddress={null}
228-
addressLength={lastAddressLength}
229-
findMemoryForWorker={findMemoryForWorkerRange(matchingRange?.startAddress || 0)}
230-
/>
231-
</div>
218+
flatData.map((byte, idx) => (
219+
<MemoryCell
220+
index={idx}
221+
address={draftStart + idx}
222+
value={byte}
223+
selectedAddress={null}
224+
findMemoryForWorker={findMemoryForWorkerRange(matchingRange?.startAddress || 0)}
225+
/>
232226
))
233227
)}
234228
</div>
@@ -244,7 +238,7 @@ function MemoryRangeRow({
244238
</PopoverTrigger>
245239
<PopoverContent className="w-auto p-2">
246240
<a
247-
href={`https://papi.fluffylabs.dev/?data=${uint8ToHex(flatData)}`}
241+
href={`https://papi.fluffylabs.dev/?data=${uint8ToHex(new Uint8Array(flatData))}`}
248242
target="_blank"
249243
rel="noreferrer"
250244
className="underline text-blue-600 block mb-2"
@@ -256,9 +250,9 @@ function MemoryRangeRow({
256250
<div>(no data)</div>
257251
) : (
258252
<div className="text-sm space-y-1 font-mono">
259-
<div>{interpretResult.u16Line}</div>
260-
<div>{interpretResult.u32Line}</div>
261-
<div>{interpretResult.u64Line}</div>
253+
{interpretResult.map((interpretation) => (
254+
<div key={interpretation}>{interpretation}</div>
255+
))}
262256
</div>
263257
)}
264258
</PopoverContent>

src/components/MemoryPreview/utils.ts

Lines changed: 114 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,61 +24,131 @@ export const addressFormatter = (address: number, numeralSystem: NumeralSystem)
2424
return numeralSystem ? `0x${addressDisplay}` : addressDisplay;
2525
};
2626

27+
// For decoding i8, i16, i24, i32, i64, u16, u24, u32, u64
28+
function decodeI8At(slice: Uint8Array, offset: number): number | null {
29+
if (offset + 1 > slice.length) return null;
30+
const dec = codec.Decoder.fromBlob(slice);
31+
dec.resetTo(offset);
32+
return dec.i8();
33+
}
34+
function decodeI16At(slice: Uint8Array, offset: number): number | null {
35+
if (offset + 2 > slice.length) return null;
36+
const dec = codec.Decoder.fromBlob(slice);
37+
dec.resetTo(offset);
38+
return dec.i16();
39+
}
40+
function decodeI24At(slice: Uint8Array, offset: number): number | null {
41+
if (offset + 3 > slice.length) return null;
42+
const dec = codec.Decoder.fromBlob(slice);
43+
dec.resetTo(offset);
44+
return dec.i24();
45+
}
46+
function decodeI32At(slice: Uint8Array, offset: number): number | null {
47+
if (offset + 4 > slice.length) return null;
48+
const dec = codec.Decoder.fromBlob(slice);
49+
dec.resetTo(offset);
50+
return dec.i32();
51+
}
52+
function decodeI64At(slice: Uint8Array, offset: number): bigint | null {
53+
if (offset + 8 > slice.length) return null;
54+
const dec = codec.Decoder.fromBlob(slice);
55+
dec.resetTo(offset);
56+
return dec.i64();
57+
}
58+
function decodeU16At(slice: Uint8Array, offset: number): number | null {
59+
if (offset + 2 > slice.length) return null;
60+
const dec = codec.Decoder.fromBlob(slice);
61+
dec.resetTo(offset);
62+
return dec.u16();
63+
}
64+
function decodeU24At(slice: Uint8Array, offset: number): number | null {
65+
if (offset + 3 > slice.length) return null;
66+
const dec = codec.Decoder.fromBlob(slice);
67+
dec.resetTo(offset);
68+
return dec.u24();
69+
}
70+
function decodeU32At(slice: Uint8Array, offset: number): number | null {
71+
if (offset + 4 > slice.length) return null;
72+
const dec = codec.Decoder.fromBlob(slice);
73+
dec.resetTo(offset);
74+
return dec.u32();
75+
}
76+
function decodeU64At(slice: Uint8Array, offset: number): bigint | null {
77+
if (offset + 8 > slice.length) return null;
78+
const dec = codec.Decoder.fromBlob(slice);
79+
dec.resetTo(offset);
80+
return dec.u64();
81+
}
82+
2783
export const getMemoryInterpretations = (bytes: Uint8Array, numeralSystem: NumeralSystem) => {
28-
if (bytes.length === 0 || bytes.length > 32) {
84+
if (bytes.length === 0) {
2985
return null;
3086
}
3187

32-
function decodeU16At(offset: number): number | null {
33-
if (offset + 2 > bytes.length) return null;
34-
const dec = codec.Decoder.fromBlob(bytes);
35-
dec.resetTo(offset);
36-
return dec.u16();
37-
}
38-
function decodeU32At(offset: number): number | null {
39-
if (offset + 4 > bytes.length) return null;
40-
const dec = codec.Decoder.fromBlob(bytes);
41-
dec.resetTo(offset);
42-
return dec.u32();
43-
}
44-
function decodeU64At(offset: number): bigint | null {
45-
if (offset + 8 > bytes.length) return null;
46-
const dec = codec.Decoder.fromBlob(bytes);
47-
dec.resetTo(offset);
48-
return dec.u64();
88+
if (bytes.length > 32) {
89+
return ["Max memory for interpretations is 32 bytes"];
4990
}
5091

5192
function fmt(value: number | bigint): string {
52-
return valueToNumeralSystem(value, numeralSystem, numeralSystem === NumeralSystem.HEXADECIMAL ? 2 : 3, false);
93+
return valueToNumeralSystem(value, numeralSystem, numeralSystem === NumeralSystem.HEXADECIMAL ? 2 : 3);
5394
}
5495

55-
const u16Arr: string[] = [];
56-
for (let i = 0; i < 16; i++) {
57-
const offset = i * 2;
58-
const val = decodeU16At(offset);
59-
if (val === null) break;
60-
u16Arr.push(fmt(val));
96+
function decodeArray(
97+
label: string,
98+
itemSize: number,
99+
maxItems: number,
100+
decodeFn: (s: Uint8Array, offset: number) => number | bigint | null,
101+
): string | null {
102+
const arr: string[] = [];
103+
for (let i = 0; i < maxItems; i++) {
104+
const offset = i * itemSize;
105+
const val = decodeFn(bytes, offset);
106+
if (val === null) break;
107+
arr.push(fmt(val));
108+
}
109+
if (arr.length === 0) {
110+
return null;
111+
}
112+
return `${label}: ${arr.join(" ")}`;
61113
}
62114

63-
const u32Arr: string[] = [];
64-
for (let i = 0; i < 8; i++) {
65-
const offset = i * 4;
66-
const val = decodeU32At(offset);
67-
if (val === null) break;
68-
u32Arr.push(fmt(val));
69-
}
115+
const lines: Array<string> = [];
70116

71-
const u64Arr: string[] = [];
72-
for (let i = 0; i < 4; i++) {
73-
const offset = i * 8;
74-
const val = decodeU64At(offset);
75-
if (val === null) break;
76-
u64Arr.push(fmt(val));
77-
}
117+
// i8 => up to 32 items
118+
const i8Line = decodeArray("i8 ", 1, 32, decodeI8At);
119+
if (i8Line) lines.push(i8Line);
120+
121+
// i16 => up to 16
122+
const i16Line = decodeArray("i16", 2, 16, decodeI16At);
123+
if (i16Line) lines.push(i16Line);
124+
125+
// u16 => up to 16
126+
const u16Line = decodeArray("u16", 2, 16, decodeU16At);
127+
if (u16Line) lines.push(u16Line);
128+
129+
// i24 => up to 10
130+
const i24Line = decodeArray("i24", 3, 10, decodeI24At);
131+
if (i24Line) lines.push(i24Line);
132+
133+
// u24 => up to 10
134+
const u24Line = decodeArray("u24", 3, 10, decodeU24At);
135+
if (u24Line) lines.push(u24Line);
136+
137+
// i32 => up to 8
138+
const i32Line = decodeArray("i32", 4, 8, decodeI32At);
139+
if (i32Line) lines.push(i32Line);
140+
141+
// u32 => up to 8
142+
const u32Line = decodeArray("u32", 4, 8, decodeU32At);
143+
if (u32Line) lines.push(u32Line);
144+
145+
// i64 => up to 4
146+
const i64Line = decodeArray("i64", 8, 4, decodeI64At);
147+
if (i64Line) lines.push(i64Line);
148+
149+
// u64 => up to 4
150+
const u64Line = decodeArray("u64", 8, 4, decodeU64At);
151+
if (u64Line) lines.push(u64Line);
78152

79-
return {
80-
u16Line: "u16: " + u16Arr.join(" "),
81-
u32Line: "u32: " + u32Arr.join(" "),
82-
u64Line: "u64: " + u64Arr.join(" "),
83-
};
153+
return lines.length > 0 ? lines : null;
84154
};

0 commit comments

Comments
 (0)