Skip to content

Commit 76f5f70

Browse files
authored
Re-enable assembly editor (#306)
* Re-enable assembly editor. * Fix re-rendering issues. * Bump to v20.7 * Hack around the assembler/disasssembler
1 parent 02bd336 commit 76f5f70

File tree

3 files changed

+45
-35
lines changed

3 files changed

+45
-35
lines changed

package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
"@reduxjs/toolkit": "^2.2.8",
3030
"@tanstack/react-virtual": "^3.10.9",
3131
"@typeberry/block": "0.0.1-447d5c4",
32-
"@typeberry/jam-host-calls": "0.0.1-83a3aec",
32+
"@typeberry/jam-host-calls": "0.0.1-459ce0b",
3333
"@typeberry/pvm-debugger-adapter": "0.1.0-83a3aec",
34-
"@typeberry/spectool-wasm": "0.18.1",
34+
"@typeberry/spectool-wasm": "0.20.8",
3535
"@uiw/react-codemirror": "^4.23.6",
3636
"blake2b": "^2.1.4",
3737
"class-variance-authority": "^0.7.0",

src/components/ProgramLoader/Assembly.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { useCallback, useEffect, useMemo, useState } from "react";
1+
import { useCallback, useMemo, useState } from "react";
22
import { ProgramUploadFileOutput } from "./types";
3-
import { InitialState } from "../../types/pvm";
3+
import { InitialState, RegistersArray } from "../../types/pvm";
44
import classNames from "classnames";
55
import { compile_assembly, disassemble } from "@typeberry/spectool-wasm";
66
import { mapUploadFileInputToOutput } from "./utils";
@@ -52,6 +52,8 @@ function assemblyFromInputProgram(initialState: InitialState, program: number[])
5252
// 4. `ecalli` instructions seem to have `// INVALID` comments next to them, but
5353
// the assembler does not handle comments at all.
5454
// 5. disassembler produces unary minus (i.e. `r0 = -r7`), which isn't handled by the compiler.
55+
// 6. disassembler produces <<r (rotate) which is not supported
56+
// 7. diassembler produces only 32-bit representation of negative values `0xffffffff`
5557
const fixedLines: string[] = lines.map((l: string) => {
5658
// remove leading whitespace
5759
l = l.trim();
@@ -65,6 +67,12 @@ function assemblyFromInputProgram(initialState: InitialState, program: number[])
6567
l = l.replace(/= -/, "= 0 -");
6668
// replace `invalid` instructions with a comment
6769
l = l.replace("invalid", "// invalid");
70+
// set first block as entry point
71+
l = l.replace("@block0", "pub @main");
72+
// replace rotate with shift (INCORRECT!)
73+
l = l.replace("<<r", "<<").replace(">>r", ">>");
74+
// replace large values with their 64-bit extensions (INCORRECT!; just for fib)
75+
l = l.replace("0xffffffff", "0xffffffffffffffff");
6876
return l;
6977
});
7078

@@ -114,7 +122,7 @@ export const Assembly = ({
114122
const newInitialState = {
115123
...initialState,
116124
};
117-
newInitialState.regs = output.initial.regs;
125+
newInitialState.regs = truncateRegs(output.initial.regs);
118126
// this is incorrect, but we would need to alter the
119127
// assembly to include the actual data:
120128
// pub @main: (pc)
@@ -130,11 +138,12 @@ export const Assembly = ({
130138
if ((output.initial.pageMap?.length ?? 0) !== 0) {
131139
newInitialState.pageMap = output.initial.pageMap;
132140
}
133-
// we want to keep all of the old stuff to avoid re-rendering.
134-
output.initial = newInitialState;
135-
// TODO [ToDr] Assembly for 64-bit is temporarily broken, so we don't trigger
136-
// the `onProgramLoad` here.
137-
// onProgramLoad(output);
141+
// if there are no changes do not re-render.
142+
if (JSON.stringify(output.initial) !== JSON.stringify(newInitialState)) {
143+
// we want to keep all of the old stuff to avoid re-rendering.
144+
output.initial = newInitialState;
145+
onProgramLoad(output);
146+
}
138147
setError(undefined);
139148
} catch (e) {
140149
if (e instanceof Error) {
@@ -157,15 +166,6 @@ export const Assembly = ({
157166

158167
const [error, setError] = useState<string>();
159168
const [assembly, setAssembly] = useState(defaultAssembly);
160-
const [isFirstCompilation, setFirstCompilation] = useState(true);
161-
162-
// compile the assembly for the first time
163-
useEffect(() => {
164-
if (isFirstCompilation) {
165-
compile(assembly);
166-
setFirstCompilation(false);
167-
}
168-
}, [compile, assembly, isFirstCompilation]);
169169

170170
const isError = !!error;
171171

@@ -195,8 +195,6 @@ export const Assembly = ({
195195
className="h-full"
196196
height="100%"
197197
placeholder="Try writing some PolkaVM assembly code."
198-
/* TODO [ToDr] Marking as readonly since the 64-bit assembly is not working correctly yet */
199-
readOnly
200198
value={assembly}
201199
onChange={compile}
202200
/>
@@ -223,3 +221,15 @@ function isArrayEqual<T>(a: T[], b: T[]) {
223221

224222
return true;
225223
}
224+
225+
function truncateRegs(regs: RegistersArray | undefined) {
226+
if (!regs) {
227+
return regs;
228+
}
229+
230+
for (let i = 0; i < regs.length; i++) {
231+
// currently the assembler requires that registers are provided as u32
232+
regs[i] = regs[i] & 0xffff_ffffn;
233+
}
234+
return regs;
235+
}

0 commit comments

Comments
 (0)