Skip to content

Commit ce66add

Browse files
Add possibility to load SPI program with metadata (#372)
* add possibility to load spi program with metadata * Update src/pages/DebuggerContent.tsx Co-authored-by: Tomek Drwięga <tomusdrw@users.noreply.github.com> * bump host calls * bump debugger adapter --------- Co-authored-by: Tomek Drwięga <tomusdrw@users.noreply.github.com>
1 parent e0c3cb9 commit ce66add

File tree

13 files changed

+71
-78
lines changed

13 files changed

+71
-78
lines changed

package-lock.json

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

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@
2929
"@radix-ui/react-tooltip": "^1.1.7",
3030
"@reduxjs/toolkit": "^2.2.8",
3131
"@tanstack/react-virtual": "^3.10.9",
32-
"@typeberry/block": "0.0.1-447d5c4",
33-
"@typeberry/jam-host-calls": "0.0.1-fece159",
34-
"@typeberry/pvm-debugger-adapter": "0.1.0-d25aae0",
32+
"@typeberry/pvm-debugger-adapter": "0.1.0-f7a7185",
3533
"@typeberry/spectool-wasm": "0.20.8",
3634
"@uiw/react-codemirror": "^4.23.6",
3735
"blake2b": "^2.1.4",

src/components/HostCalls/trie-input/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Textarea } from "@/components/ui/textarea";
44
import { cn } from "@/lib/utils";
55
import { hasPVMGeneratedStorage } from "@/store/debugger/debuggerSlice";
66
import { useAppSelector } from "@/store/hooks";
7-
import { bytes, hash } from "@typeberry/jam-host-calls";
7+
import { bytes, hash } from "@typeberry/pvm-debugger-adapter";
88
import { cloneDeep } from "lodash";
99
import { XIcon } from "lucide-react";
1010
import { useEffect, useState } from "react";

src/components/MemoryPreview/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { NumeralSystem } from "@/context/NumeralSystem";
22
import { WorkerState } from "@/store/workers/workersSlice";
33
import { valueToNumeralSystem } from "../Instructions/utils";
4-
import { codec } from "@typeberry/block";
4+
import { block } from "@typeberry/pvm-debugger-adapter";
5+
6+
const codec = block.codec;
57

68
export type FindMemoryForWorkerType = (
79
worker: WorkerState,

src/components/ProgramTextLoader/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Textarea } from "@/components/ui/textarea.tsx";
22
import React, { useMemo, useState } from "react";
33
import classNames from "classnames";
4-
import { bytes } from "@typeberry/block";
4+
import { bytes } from "@typeberry/pvm-debugger-adapter";
55
import { logger } from "@/utils/loggerService";
66
import { useAppSelector } from "@/store/hooks.ts";
77
import { selectIsProgramInvalid } from "@/store/debugger/debuggerSlice.ts";

src/packages/host-calls/read.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { block, bytes, hash, read } from "@typeberry/jam-host-calls";
1+
import { block, bytes, hash, read } from "@typeberry/pvm-debugger-adapter";
22
import { Storage } from "../web-worker/types";
33

44
export class ReadAccounts implements read.Accounts {

src/packages/host-calls/write.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { write, hash, block, bytes } from "@typeberry/jam-host-calls";
1+
import { write, hash, block, bytes } from "@typeberry/pvm-debugger-adapter";
22
import { Storage } from "../web-worker/types";
33

44
export class WriteAccounts implements write.Accounts {

src/packages/web-worker/command-handlers/host-call.ts

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
import { HostCallIdentifiers } from "@/types/pvm";
22
import { CommandStatus, PvmApiInterface, Storage } from "../types";
3-
import { read, Registers, write, Memory, gas } from "@typeberry/jam-host-calls";
3+
import {
4+
read,
5+
write,
6+
gas,
7+
HostCallRegisters,
8+
Result,
9+
interpreter,
10+
numbers,
11+
Registers,
12+
IHostCallMemory,
13+
IHostCallRegisters,
14+
OK,
15+
HostCallMemory,
16+
} from "@typeberry/pvm-debugger-adapter";
417
import { WriteAccounts } from "@/packages/host-calls/write";
518
import { isInternalPvm } from "../utils";
619
import { ReadAccounts } from "@/packages/host-calls/read";
7-
import { tryAsServiceId } from "@typeberry/block";
8-
import { Gas, MemoryIndex, tryAsGas } from "@typeberry/pvm-debugger-adapter";
20+
import { block } from "@typeberry/pvm-debugger-adapter";
921
import { WasmPvmShellInterface } from "../wasmBindgenShell";
1022

23+
const { tryAsGas } = interpreter;
24+
const { tryAsU64 } = numbers;
25+
const { tryAsServiceId } = block;
1126
type HostCallParams = {
1227
pvm: PvmApiInterface | null;
1328
hostCallIdentifier: HostCallIdentifiers;
@@ -31,15 +46,15 @@ type HostCallResponse =
3146
class SimpleGas {
3247
pvm!: WasmPvmShellInterface;
3348

34-
get(): Gas {
49+
get() {
3550
return tryAsGas(this.pvm.getGasLeft());
3651
}
37-
set(gas: Gas) {
52+
set(gas: interpreter.Gas) {
3853
if (this.pvm.setGasLeft) {
3954
this.pvm.setGasLeft(BigInt(gas));
4055
}
4156
}
42-
sub(v: Gas) {
57+
sub(v: interpreter.Gas) {
4358
const current = this.get();
4459
if (current > v) {
4560
this.set(tryAsGas(BigInt(current) - BigInt(v)));
@@ -61,76 +76,62 @@ const getGasCounter = (pvm: PvmApiInterface) => {
6176

6277
return gas;
6378
};
64-
65-
class SimpleRegisters implements Registers {
79+
class SimpleRegisters implements IHostCallRegisters {
6680
flatRegisters!: Uint8Array;
6781
pvm!: WasmPvmShellInterface;
6882

69-
getU32(registerIndex: number): number {
70-
return Number(this.getU64(registerIndex) & 0xffff_ffffn);
71-
}
72-
getI32(registerIndex: number): number {
73-
return Number(this.getU32(registerIndex)) >> 0;
74-
}
75-
setU32(registerIndex: number, value: number): void {
76-
this.setU64(registerIndex, BigInt(value));
77-
}
78-
setI32(registerIndex: number, value: number): void {
79-
this.setI64(registerIndex, BigInt(value));
83+
get(registerIndex: number): numbers.U64 {
84+
return tryAsU64(new BigUint64Array(this.flatRegisters.buffer)[registerIndex]);
8085
}
81-
getU64(registerIndex: number): bigint {
82-
return new BigUint64Array(this.flatRegisters.buffer)[registerIndex];
83-
}
84-
getI64(registerIndex: number): bigint {
85-
return new BigInt64Array(this.flatRegisters.buffer)[registerIndex];
86-
}
87-
setU64(registerIndex: number, value: bigint): void {
86+
87+
set(registerIndex: number, value: numbers.U64): void {
8888
new BigUint64Array(this.flatRegisters.buffer)[registerIndex] = value;
8989
this.pvm.setRegisters(this.flatRegisters);
9090
}
91-
setI64(registerIndex: number, value: bigint): void {
92-
new BigInt64Array(this.flatRegisters.buffer)[registerIndex] = value;
93-
this.pvm.setRegisters(this.flatRegisters);
94-
}
9591
}
9692

9793
const getRegisters = (pvm: PvmApiInterface) => {
9894
if (isInternalPvm(pvm)) {
99-
return pvm.getInterpreter().getRegisters();
95+
const regs = pvm.getInterpreter().getRegisters();
96+
return new HostCallRegisters(regs);
10097
}
10198

10299
const registers = new SimpleRegisters();
100+
const regs = new Registers();
101+
const rawRegs = new BigUint64Array(pvm.getRegisters().buffer);
102+
regs.copyFrom(rawRegs);
103103
registers.flatRegisters = pvm.getRegisters();
104104
registers.pvm = pvm;
105105

106106
return registers;
107107
};
108108

109-
class SimpleMemory implements Memory {
109+
class SimpleMemory implements IHostCallMemory {
110110
pvm!: WasmPvmShellInterface;
111111
memorySize: number = 4096;
112112

113-
loadInto(result: Uint8Array, startAddress: MemoryIndex) {
114-
const memoryDump = this.pvm.getPageDump(startAddress / this.memorySize);
113+
loadInto(result: Uint8Array, startAddress: numbers.U64) {
114+
const memoryDump = this.pvm.getPageDump(Number(startAddress / tryAsU64(this.memorySize)));
115115
result.set(memoryDump.subarray(0, result.length));
116116

117-
return null;
118-
}
119-
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
120-
isWriteable(_destinationStart: MemoryIndex, _length: number) {
121-
return true;
117+
return Result.ok(OK);
122118
}
123119

124-
storeFrom(address: MemoryIndex, bytes: Uint8Array) {
120+
storeFrom(address: numbers.U64, bytes: Uint8Array) {
125121
// TODO [ToDr] Either change the API to require handling multi-page writes or change this code to split the write into multiple pages.
126-
this.pvm.setMemory(address, bytes);
127-
return null;
122+
this.pvm.setMemory(Number(address), bytes);
123+
return Result.ok(OK);
124+
}
125+
126+
getMemory() {
127+
// TODO [MaSi]: This function is used only by `peek` and `poke` host calls, so dummy implementation is okay for now.
128+
return new interpreter.Memory();
128129
}
129130
}
130131

131132
const getMemory = (pvm: PvmApiInterface) => {
132133
if (isInternalPvm(pvm)) {
133-
return pvm.getInterpreter().getMemory();
134+
return new HostCallMemory(pvm.getInterpreter().getMemory());
134135
}
135136
const memory = new SimpleMemory();
136137
memory.pvm = pvm;
@@ -174,7 +175,7 @@ const hostCall = async ({
174175

175176
return { hostCallIdentifier, storage, status: CommandStatus.SUCCESS };
176177
} else if (hostCallIdentifier === HostCallIdentifiers.GAS) {
177-
const jamHostCall = new gas.Gas();
178+
const jamHostCall = new gas.GasHostCall();
178179

179180
await jamHostCall.execute(getGasCounter(pvm), getRegisters(pvm));
180181

src/packages/web-worker/pvm.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { InitialState, Pvm as InternalPvm, Status } from "@/types/pvm";
22
import {
33
createResults,
44
instructionArgumentTypeMap,
5+
interpreter,
56
ProgramDecoder,
6-
tryAsMemoryIndex,
7-
tryAsSbrkIndex,
87
} from "@typeberry/pvm-debugger-adapter";
98
import { ArgsDecoder, Registers } from "@typeberry/pvm-debugger-adapter";
109
import { byteToOpCodeMap } from "../../packages/pvm/pvm/assemblify";
11-
import { Pvm as InternalPvmInstance, MemoryBuilder as InternalPvmMemoryBuilder } from "@typeberry/pvm-debugger-adapter";
10+
import { Pvm as InternalPvmInstance } from "@typeberry/pvm-debugger-adapter";
11+
12+
const { tryAsMemoryIndex, tryAsSbrkIndex, MemoryBuilder: InternalPvmMemoryBuilder } = interpreter;
13+
1214
export const initPvm = async (pvm: InternalPvmInstance, program: Uint8Array, initialState: InitialState) => {
1315
const initialMemory = initialState.memory ?? [];
1416
const pageMap = initialState.pageMap ?? [];
@@ -34,7 +36,7 @@ export const initPvm = async (pvm: InternalPvmInstance, program: Uint8Array, ini
3436
const pageSize = 2 ** 12;
3537
const maxAddressFromPageMap = Math.max(...pageMap.map((page) => page.address + page.length));
3638
const hasMemoryLayout = maxAddressFromPageMap >= 0;
37-
const heapStartIndex = tryAsSbrkIndex(hasMemoryLayout ? maxAddressFromPageMap + pageSize : 0);
39+
const heapStartIndex = tryAsMemoryIndex(hasMemoryLayout ? maxAddressFromPageMap + pageSize : 0);
3840
const heapEndIndex = tryAsSbrkIndex(2 ** 32 - 2 * 2 ** 16 - 2 ** 24);
3941

4042
const memory = memoryBuilder.finalize(heapStartIndex, heapEndIndex);

src/packages/web-worker/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CurrentInstruction, ExpectedState, HostCallIdentifiers, InitialState } from "@/types/pvm";
22
import { WasmPvmShellInterface } from "./wasmBindgenShell";
33
import { Pvm as InternalPvm } from "@/types/pvm";
4-
import { bytes } from "@typeberry/jam-host-calls";
4+
import { bytes } from "@typeberry/pvm-debugger-adapter";
55
import { SerializedFile } from "@/lib/utils.ts";
66

77
type CommonWorkerResponseParams = { status: CommandStatus; error?: unknown; messageId: string };

src/pages/DebuggerContent.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ const DebuggerContent = () => {
138138
dispatch(setIsProgramInvalid(true));
139139
}
140140

141-
function tryAsSpi(program: number[]) {
141+
function tryAsSpi(program: number[], withMetadata: boolean) {
142142
try {
143143
const { code, memory, registers } = Program.fromSpi(
144144
new Uint8Array(program),
145145
new Uint8Array(),
146+
withMetadata,
146147
);
147148
const regs = Array.from(registers.getAllU64()) as RegistersArray;
148149
return {
@@ -156,7 +157,9 @@ const DebuggerContent = () => {
156157
}
157158

158159
if (!error && program) {
159-
const maybeSpi = tryAsSpi(program.slice());
160+
const maybeSpiWithMetadata = tryAsSpi(program.slice(), true);
161+
const maybeSpiWithoutMetadata = tryAsSpi(program.slice(), false);
162+
const maybeSpi = maybeSpiWithoutMetadata || maybeSpiWithMetadata;
160163
if (maybeSpi) {
161164
debuggerActions.handleProgramLoad(maybeSpi);
162165
} else {

src/pages/ProgramLoader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Loader } from "@/components/ProgramLoader/Loader.tsx";
22
import { useEffect, useRef } from "react";
3-
import { bytes } from "@typeberry/block";
3+
import { bytes } from "@typeberry/pvm-debugger-adapter";
44
import { decodeStandardProgram } from "@typeberry/pvm-debugger-adapter";
55
import { MemoryChunkItem, PageMapItem, RegistersArray } from "@/types/pvm.ts";
66
import { useNavigate } from "react-router";

src/store/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { DebuggerEcalliStorage } from "@/types/pvm";
1010
import { logger } from "@/utils/loggerService";
1111
import { SerializedError } from "@reduxjs/toolkit";
12-
import { bytes } from "@typeberry/jam-host-calls";
12+
import { bytes } from "@typeberry/pvm-debugger-adapter";
1313

1414
const RESPONSE_WAIT_TIMEOUT = 60000;
1515
const getMessageId = () => Math.random().toString(36).substring(7);

0 commit comments

Comments
 (0)