mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-19 19:53:56 +00:00
Prepare web debugger (#247)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -150,4 +150,6 @@ user*.bat
|
||||
|
||||
page/public/analyzer.js
|
||||
page/public/analyzer.wasm
|
||||
page/public/debugger.js
|
||||
page/public/debugger.wasm
|
||||
page/public/root.zip
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -18,3 +18,9 @@
|
||||
[submodule "deps/gtest-parallel"]
|
||||
path = deps/gtest-parallel
|
||||
url = https://github.com/google/gtest-parallel.git
|
||||
[submodule "deps/flatbuffers"]
|
||||
path = deps/flatbuffers
|
||||
url = https://github.com/google/flatbuffers.git
|
||||
[submodule "deps/base64"]
|
||||
path = deps/base64
|
||||
url = https://github.com/tobiaslocker/base64.git
|
||||
|
||||
@@ -92,6 +92,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||
momo_add_c_and_cxx_compile_options(
|
||||
-fexceptions
|
||||
-ftrivial-auto-var-init=zero
|
||||
-Wno-dollar-in-identifier-extension
|
||||
)
|
||||
|
||||
add_link_options(
|
||||
|
||||
15
deps/CMakeLists.txt
vendored
15
deps/CMakeLists.txt
vendored
@@ -3,6 +3,21 @@ add_subdirectory(unicorn)
|
||||
|
||||
##########################################
|
||||
|
||||
option(BASE64_ENABLE_TESTING "" OFF)
|
||||
add_subdirectory(base64)
|
||||
|
||||
##########################################
|
||||
|
||||
option(FLATBUFFERS_BUILD_TESTS "" OFF)
|
||||
option(FLATBUFFERS_INSTALL "" OFF)
|
||||
add_subdirectory(flatbuffers)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(flatc PRIVATE /MD)
|
||||
endif()
|
||||
|
||||
##########################################
|
||||
|
||||
add_library(reflect INTERFACE)
|
||||
target_include_directories(reflect INTERFACE
|
||||
"${CMAKE_CURRENT_LIST_DIR}/reflect"
|
||||
|
||||
1
deps/base64
vendored
Submodule
1
deps/base64
vendored
Submodule
Submodule deps/base64 added at 0d0f5a8849
1
deps/flatbuffers
vendored
Submodule
1
deps/flatbuffers
vendored
Submodule
Submodule deps/flatbuffers added at 609c72ca1a
@@ -1,2 +1,3 @@
|
||||
# Ignore artifacts:
|
||||
dist
|
||||
src/fb/
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
<title>Sogen - Windows User Space Emulator</title>
|
||||
|
||||
<meta name="color-scheme" content="dark" />
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
content="Sogen is a high-performance Windows user space emulator that can emulate windows processes. It is ideal for security-, DRM- or malware research."
|
||||
|
||||
88
page/package-lock.json
generated
88
page/package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@fontsource/inter": "^5.2.5",
|
||||
"@radix-ui/react-checkbox": "^1.2.3",
|
||||
"@radix-ui/react-dialog": "^1.1.11",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.12",
|
||||
"@radix-ui/react-label": "^2.1.4",
|
||||
"@radix-ui/react-popover": "^1.1.11",
|
||||
"@radix-ui/react-scroll-area": "^1.2.6",
|
||||
@@ -22,12 +23,14 @@
|
||||
"@types/react-window": "^1.8.8",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"flatbuffers": "^25.2.10",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.503.0",
|
||||
"react": "^19.0.0",
|
||||
"react-bootstrap-icons": "^1.11.5",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-resizable-panels": "^2.1.9",
|
||||
"react-router-dom": "^7.5.2",
|
||||
"react-window": "^1.8.11",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
@@ -1424,6 +1427,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dropdown-menu": {
|
||||
"version": "2.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.12.tgz",
|
||||
"integrity": "sha512-VJoMs+BWWE7YhzEQyVwvF9n22Eiyr83HotCVrMQzla/OwRovXCgah7AcaEr4hMNj4gJxSdtIbcHGvmJXOoJVHA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.2",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-menu": "2.1.12",
|
||||
"@radix-ui/react-primitive": "2.1.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-focus-guards": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz",
|
||||
@@ -1505,6 +1537,46 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-menu": {
|
||||
"version": "2.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.12.tgz",
|
||||
"integrity": "sha512-+qYq6LfbiGo97Zz9fioX83HCiIYYFNs8zAsVCMQrIakoNYylIzWuoD/anAD3UzvvR6cnswmfRFJFq/zYYq/k7Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.2",
|
||||
"@radix-ui/react-collection": "1.1.4",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-direction": "1.1.1",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.7",
|
||||
"@radix-ui/react-focus-guards": "1.1.2",
|
||||
"@radix-ui/react-focus-scope": "1.1.4",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-popper": "1.2.4",
|
||||
"@radix-ui/react-portal": "1.1.6",
|
||||
"@radix-ui/react-presence": "1.1.4",
|
||||
"@radix-ui/react-primitive": "2.1.0",
|
||||
"@radix-ui/react-roving-focus": "1.1.7",
|
||||
"@radix-ui/react-slot": "1.2.0",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.1",
|
||||
"aria-hidden": "^1.2.4",
|
||||
"react-remove-scroll": "^2.6.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popover": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.11.tgz",
|
||||
@@ -3595,6 +3667,12 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/flatbuffers": {
|
||||
"version": "25.2.10",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.2.10.tgz",
|
||||
"integrity": "sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
||||
@@ -4625,6 +4703,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-resizable-panels": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz",
|
||||
"integrity": "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.5.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"@fontsource/inter": "^5.2.5",
|
||||
"@radix-ui/react-checkbox": "^1.2.3",
|
||||
"@radix-ui/react-dialog": "^1.1.11",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.12",
|
||||
"@radix-ui/react-label": "^2.1.4",
|
||||
"@radix-ui/react-popover": "^1.1.11",
|
||||
"@radix-ui/react-scroll-area": "^1.2.6",
|
||||
@@ -24,12 +25,14 @@
|
||||
"@types/react-window": "^1.8.8",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"flatbuffers": "^25.2.10",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.503.0",
|
||||
"react": "^19.0.0",
|
||||
"react-bootstrap-icons": "^1.11.5",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-resizable-panels": "^2.1.9",
|
||||
"react-router-dom": "^7.5.2",
|
||||
"react-window": "^1.8.11",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
var logLines = [];
|
||||
var lastFlush = new Date().getTime();
|
||||
|
||||
var msgQueue = [];
|
||||
|
||||
onmessage = async (event) => {
|
||||
const data = event.data;
|
||||
if (data.message == "run") {
|
||||
const payload = data.data;
|
||||
runEmulation(payload.filesystem, payload.file, payload.options);
|
||||
} else if (data.message == "event") {
|
||||
const payload = data.data;
|
||||
msgQueue.push(payload);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,6 +37,18 @@ function notifyExit(code) {
|
||||
self.close();
|
||||
}
|
||||
|
||||
function handleMessage(message) {
|
||||
postMessage({ message: "event", data: message });
|
||||
}
|
||||
|
||||
function getMessageFromQueue() {
|
||||
if (msgQueue.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return msgQueue.shift();
|
||||
}
|
||||
|
||||
function runEmulation(filesystem, file, options) {
|
||||
globalThis.Module = {
|
||||
arguments: [...options, "-e", "./root", file],
|
||||
|
||||
@@ -5,32 +5,74 @@ html {
|
||||
@media (pointer: fine) {
|
||||
::-webkit-scrollbar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(97, 97, 97, 0.7);
|
||||
border-radius: 20px;
|
||||
min-height: 50px;
|
||||
border: 6px solid transparent;
|
||||
background-clip: content-box;
|
||||
transition: all 0.1s linear;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: rgba(97, 97, 97, 0.9);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.fancy-primary,
|
||||
button.fancy-secondary {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
button.fancy-primary {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(38, 144, 255, 1) 0%,
|
||||
rgba(0, 123, 255, 1) 100%
|
||||
);
|
||||
border: 1px solid rgb(18, 101, 236);
|
||||
text-shadow: rgba(0, 0, 0, 0.2) 0px 1px;
|
||||
}
|
||||
|
||||
button.fancy-primary:hover {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(46, 151, 255, 1) 0%,
|
||||
rgba(8, 130, 255, 1) 100%
|
||||
);
|
||||
border: 1px solid rgb(33, 33, 34);
|
||||
}
|
||||
|
||||
button.fancy-secondary {
|
||||
background: linear-gradient(180deg, rgb(38, 38, 39) 0%, rgb(34, 34, 35) 100%);
|
||||
border: 1px solid rgb(42, 42, 44);
|
||||
}
|
||||
|
||||
button.fancy-secondary:hover {
|
||||
background: linear-gradient(180deg, rgb(42, 42, 43) 0%, rgb(38, 38, 39) 100%);
|
||||
border: 1px solid rgb(33, 33, 34);
|
||||
}
|
||||
|
||||
.terminal-output span {
|
||||
padding: 0px 16px;
|
||||
}
|
||||
|
||||
.terminal-output {
|
||||
line-height: 1.5;
|
||||
font-weight: 600;
|
||||
font-size: 1.05em;
|
||||
font-family: monospace;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useRef } from "react";
|
||||
import { useState, useRef, useReducer } from "react";
|
||||
import { Output } from "@/components/output";
|
||||
|
||||
import { AppSidebar } from "@/components/app-sidebar";
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
SidebarProvider,
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { Button } from "./components/ui/button";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
import { Emulator, UserFile } from "./emulator";
|
||||
import { Emulator, UserFile, EmulationState } from "./emulator";
|
||||
import { getFilesystem } from "./filesystem";
|
||||
|
||||
import "./App.css";
|
||||
@@ -18,14 +18,36 @@ import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "./components/ui/popover";
|
||||
} from "@/components/ui/popover";
|
||||
|
||||
import { createDefaultSettings } from "./settings";
|
||||
import { SettingsMenu } from "./components/settings-menu";
|
||||
import { SettingsMenu } from "@/components/settings-menu";
|
||||
|
||||
import { PlayFill, StopFill, GearFill } from "react-bootstrap-icons";
|
||||
import { StatusIndicator } from "./components/status-indicator";
|
||||
import {
|
||||
PlayFill,
|
||||
StopFill,
|
||||
GearFill,
|
||||
PauseFill,
|
||||
FileEarmarkCheckFill,
|
||||
ImageFill,
|
||||
} from "react-bootstrap-icons";
|
||||
import { StatusIndicator } from "@/components/status-indicator";
|
||||
import { Header } from "./Header";
|
||||
import {
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
} from "@/components/ui/resizable";
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuGroup,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
function selectAndReadFile(): Promise<UserFile> {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -64,6 +86,7 @@ export function Playground() {
|
||||
const output = useRef<Output>(null);
|
||||
const [settings, setSettings] = useState(createDefaultSettings());
|
||||
const [emulator, setEmulator] = useState<Emulator | null>(null);
|
||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||
|
||||
function logLine(line: string) {
|
||||
output.current?.logLine(line);
|
||||
@@ -73,6 +96,18 @@ export function Playground() {
|
||||
output.current?.logLines(lines);
|
||||
}
|
||||
|
||||
function isEmulatorPaused() {
|
||||
return emulator && emulator.getState() == EmulationState.Paused;
|
||||
}
|
||||
|
||||
function toggleEmulatorState() {
|
||||
if (isEmulatorPaused()) {
|
||||
emulator?.resume();
|
||||
} else {
|
||||
emulator?.pause();
|
||||
}
|
||||
}
|
||||
|
||||
async function createEmulator(userFile: UserFile | null = null) {
|
||||
emulator?.stop();
|
||||
output.current?.clear();
|
||||
@@ -83,7 +118,7 @@ export function Playground() {
|
||||
logLine(`Processing filesystem (${current}/${total}): ${file}`);
|
||||
});
|
||||
|
||||
const new_emulator = new Emulator(fs, logLines);
|
||||
const new_emulator = new Emulator(fs, logLines, (_) => forceUpdate());
|
||||
new_emulator.onTerminate().then(() => setEmulator(null));
|
||||
setEmulator(new_emulator);
|
||||
|
||||
@@ -104,22 +139,62 @@ export function Playground() {
|
||||
<SidebarProvider defaultOpen={false}>
|
||||
<AppSidebar />
|
||||
<SidebarInset className="h-[100dvh]">
|
||||
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4 overflow-y-auto">
|
||||
<SidebarTrigger className="-ml-1" />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
<Button onClick={() => createEmulator()}>
|
||||
<PlayFill /> Run Sample
|
||||
<header className="flex shrink-0 items-center gap-2 border-b p-2 overflow-y-auto">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="h-4" />
|
||||
|
||||
{/* RUN */}
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="sm">
|
||||
<PlayFill /> Run
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56">
|
||||
<DropdownMenuLabel>Run Application</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onClick={() => createEmulator()}>
|
||||
<ImageFill className="mr-2" />
|
||||
<span>Select Sample</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => loadAndRunUserFile()}>
|
||||
<FileEarmarkCheckFill className="mr-2" />
|
||||
<span>Seelct your .exe</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<Button
|
||||
disabled={!emulator}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={() => emulator?.stop()}
|
||||
>
|
||||
<StopFill /> Stop
|
||||
</Button>
|
||||
<Button onClick={() => loadAndRunUserFile()}>
|
||||
<PlayFill /> Run your .exe
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={() => emulator?.stop()}>
|
||||
<StopFill /> Stop Emulation
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={!emulator}
|
||||
variant="secondary"
|
||||
onClick={toggleEmulatorState}
|
||||
>
|
||||
{isEmulatorPaused() ? (
|
||||
<>
|
||||
<PlayFill /> Resume
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<PauseFill /> Pause
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="secondary">
|
||||
<Button size="sm" variant="secondary">
|
||||
<GearFill /> Settings
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
@@ -128,10 +203,12 @@ export function Playground() {
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div className="text-right flex-1">
|
||||
<StatusIndicator running={!!emulator} />
|
||||
<StatusIndicator
|
||||
state={emulator ? emulator.getState() : EmulationState.Stopped}
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1 flex-col gap-4 p-4 overflow-auto">
|
||||
<div className="flex flex-1 flex-col overflow-auto pt-4">
|
||||
<Output ref={output} />
|
||||
</div>
|
||||
</SidebarInset>
|
||||
|
||||
@@ -1,28 +1,48 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { CircleFill } from "react-bootstrap-icons";
|
||||
import { EmulationState as State } from "@/emulator";
|
||||
|
||||
function getStateName(state: State) {
|
||||
switch (state) {
|
||||
case State.Stopped:
|
||||
return "Stopped";
|
||||
case State.Paused:
|
||||
return "Paused";
|
||||
case State.Running:
|
||||
return "Running";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function getStateColor(state: State) {
|
||||
switch (state) {
|
||||
case State.Stopped:
|
||||
return "bg-orange-600";
|
||||
case State.Paused:
|
||||
return "bg-amber-500";
|
||||
case State.Running:
|
||||
return "bg-lime-600";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export interface StatusIndicatorProps {
|
||||
running: boolean;
|
||||
state: State;
|
||||
}
|
||||
|
||||
export function StatusIndicator(props: StatusIndicatorProps) {
|
||||
const getText = () => {
|
||||
return props.running ? " Running" : " Stopped";
|
||||
};
|
||||
|
||||
const getColor = () => {
|
||||
return props.running ? "bg-lime-600" : "bg-orange-600";
|
||||
};
|
||||
|
||||
return (
|
||||
<Badge variant="outline">
|
||||
<CircleFill
|
||||
className={
|
||||
getColor() + " rounded-full mr-1 n duration-200 ease-in-out"
|
||||
getStateColor(props.state) +
|
||||
" rounded-full mr-1 n duration-200 ease-in-out"
|
||||
}
|
||||
color="transparent"
|
||||
/>
|
||||
{getText()}
|
||||
{getStateName(props.state)}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ const buttonVariants = cva(
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 fancy-primary",
|
||||
destructive:
|
||||
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
outline:
|
||||
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80 fancy-secondary",
|
||||
ghost:
|
||||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
|
||||
255
page/src/components/ui/dropdown-menu.tsx
Normal file
255
page/src/components/ui/dropdown-menu.tsx
Normal file
@@ -0,0 +1,255 @@
|
||||
import * as React from "react";
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function DropdownMenu({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
||||
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
||||
}
|
||||
|
||||
function DropdownMenuPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuTrigger({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Trigger
|
||||
data-slot="dropdown-menu-trigger"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuContent({
|
||||
className,
|
||||
sideOffset = 4,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
data-slot="dropdown-menu-content"
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuGroup({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuItem({
|
||||
className,
|
||||
inset,
|
||||
variant = "default",
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean;
|
||||
variant?: "default" | "destructive";
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Item
|
||||
data-slot="dropdown-menu-item"
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuCheckboxItem({
|
||||
className,
|
||||
children,
|
||||
checked,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CheckIcon className="size-4" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuRadioGroup({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioGroup
|
||||
data-slot="dropdown-menu-radio-group"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuRadioItem({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CircleIcon className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.RadioItem>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuLabel({
|
||||
className,
|
||||
inset,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
||||
inset?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Label
|
||||
data-slot="dropdown-menu-label"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuSeparator({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
data-slot="dropdown-menu-separator"
|
||||
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuShortcut({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<"span">) {
|
||||
return (
|
||||
<span
|
||||
data-slot="dropdown-menu-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground ml-auto text-xs tracking-widest",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuSub({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
||||
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
||||
}
|
||||
|
||||
function DropdownMenuSubTrigger({
|
||||
className,
|
||||
inset,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
inset?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
data-slot="dropdown-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRightIcon className="ml-auto size-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
function DropdownMenuSubContent({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export {
|
||||
DropdownMenu,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuShortcut,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuSubContent,
|
||||
};
|
||||
54
page/src/components/ui/resizable.tsx
Normal file
54
page/src/components/ui/resizable.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as React from "react";
|
||||
import { GripVerticalIcon } from "lucide-react";
|
||||
import * as ResizablePrimitive from "react-resizable-panels";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function ResizablePanelGroup({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {
|
||||
return (
|
||||
<ResizablePrimitive.PanelGroup
|
||||
data-slot="resizable-panel-group"
|
||||
className={cn(
|
||||
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function ResizablePanel({
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.Panel>) {
|
||||
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
|
||||
}
|
||||
|
||||
function ResizableHandle({
|
||||
withHandle,
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
||||
withHandle?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<ResizablePrimitive.PanelResizeHandle
|
||||
data-slot="resizable-handle"
|
||||
className={cn(
|
||||
"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
|
||||
<GripVerticalIcon className="size-2.5" />
|
||||
</div>
|
||||
)}
|
||||
</ResizablePrimitive.PanelResizeHandle>
|
||||
);
|
||||
}
|
||||
|
||||
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|
||||
@@ -1,6 +1,10 @@
|
||||
import { createDefaultSettings, Settings, translateSettings } from "./settings";
|
||||
import { FileEntry } from "./zip-file";
|
||||
|
||||
import * as flatbuffers from "flatbuffers";
|
||||
import * as fbDebugger from "@/fb/debugger";
|
||||
import * as fbDebuggerEvent from "@/fb/debugger/event";
|
||||
|
||||
type LogHandler = (lines: string[]) => void;
|
||||
|
||||
export interface UserFile {
|
||||
@@ -8,17 +12,61 @@ export interface UserFile {
|
||||
data: ArrayBuffer;
|
||||
}
|
||||
|
||||
export enum EmulationState {
|
||||
Stopped,
|
||||
Paused,
|
||||
Running,
|
||||
}
|
||||
|
||||
function base64Encode(uint8Array: Uint8Array): string {
|
||||
let binaryString = "";
|
||||
for (let i = 0; i < uint8Array.byteLength; i++) {
|
||||
binaryString += String.fromCharCode(uint8Array[i]);
|
||||
}
|
||||
|
||||
return btoa(binaryString);
|
||||
}
|
||||
|
||||
function base64Decode(data: string) {
|
||||
const binaryString = atob(data);
|
||||
|
||||
const len = binaryString.length;
|
||||
const bytes = new Uint8Array(len);
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function decodeEvent(data: string) {
|
||||
const array = base64Decode(data);
|
||||
const buffer = new flatbuffers.ByteBuffer(array);
|
||||
const event = fbDebugger.DebugEvent.getRootAsDebugEvent(buffer);
|
||||
return event.unpack();
|
||||
}
|
||||
|
||||
type StateChangeHandler = (state: EmulationState) => void;
|
||||
|
||||
export class Emulator {
|
||||
filesystem: FileEntry[];
|
||||
logHandler: LogHandler;
|
||||
stateChangeHandler: StateChangeHandler;
|
||||
terminatePromise: Promise<number | null>;
|
||||
terminateResolve: (value: number | null) => void;
|
||||
terminateReject: (reason?: any) => void;
|
||||
worker: Worker;
|
||||
state: EmulationState = EmulationState.Stopped;
|
||||
|
||||
constructor(filesystem: FileEntry[], logHandler: LogHandler) {
|
||||
constructor(
|
||||
filesystem: FileEntry[],
|
||||
logHandler: LogHandler,
|
||||
stateChangeHandler: StateChangeHandler,
|
||||
) {
|
||||
this.filesystem = filesystem;
|
||||
this.logHandler = logHandler;
|
||||
this.stateChangeHandler = stateChangeHandler;
|
||||
this.terminateResolve = () => {};
|
||||
this.terminateReject = () => {};
|
||||
this.terminatePromise = new Promise((resolve, reject) => {
|
||||
@@ -30,13 +78,7 @@ export class Emulator {
|
||||
/*new URL('./emulator-worker.js', import.meta.url)*/ "./emulator-worker.js",
|
||||
);
|
||||
|
||||
this.worker.onmessage = (event: MessageEvent) => {
|
||||
if (event.data.message == "log") {
|
||||
this.logHandler(event.data.data);
|
||||
} else if (event.data.message == "end") {
|
||||
this.terminateResolve(0);
|
||||
}
|
||||
};
|
||||
this.worker.onmessage = this._onMessage.bind(this);
|
||||
}
|
||||
|
||||
start(
|
||||
@@ -54,6 +96,7 @@ export class Emulator {
|
||||
});
|
||||
}
|
||||
|
||||
this._setState(EmulationState.Running);
|
||||
this.worker.postMessage({
|
||||
message: "run",
|
||||
data: {
|
||||
@@ -64,6 +107,19 @@ export class Emulator {
|
||||
});
|
||||
}
|
||||
|
||||
updateState() {
|
||||
this.sendEvent(
|
||||
new fbDebugger.DebugEventT(
|
||||
fbDebugger.Event.GetStateRequest,
|
||||
new fbDebugger.GetStateRequestT(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.worker.terminate();
|
||||
this.terminateResolve(null);
|
||||
@@ -72,4 +128,80 @@ export class Emulator {
|
||||
onTerminate() {
|
||||
return this.terminatePromise;
|
||||
}
|
||||
|
||||
sendEvent(event: fbDebugger.DebugEventT) {
|
||||
const builder = new flatbuffers.Builder(1024);
|
||||
fbDebugger.DebugEvent.finishDebugEventBuffer(builder, event.pack(builder));
|
||||
|
||||
const message = base64Encode(builder.asUint8Array());
|
||||
|
||||
this.worker.postMessage({
|
||||
message: "event",
|
||||
data: message,
|
||||
});
|
||||
}
|
||||
|
||||
pause() {
|
||||
this.sendEvent(
|
||||
new fbDebugger.DebugEventT(
|
||||
fbDebugger.Event.PauseRequest,
|
||||
new fbDebugger.PauseRequestT(),
|
||||
),
|
||||
);
|
||||
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
resume() {
|
||||
this.sendEvent(
|
||||
new fbDebugger.DebugEventT(
|
||||
fbDebugger.Event.RunRequest,
|
||||
new fbDebugger.RunRequestT(),
|
||||
),
|
||||
);
|
||||
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
_onMessage(event: MessageEvent) {
|
||||
if (event.data.message == "log") {
|
||||
this.logHandler(event.data.data);
|
||||
} else if (event.data.message == "event") {
|
||||
this._onEvent(decodeEvent(event.data.data));
|
||||
} else if (event.data.message == "end") {
|
||||
this._setState(EmulationState.Stopped);
|
||||
this.terminateResolve(0);
|
||||
}
|
||||
}
|
||||
|
||||
_onEvent(event: fbDebugger.DebugEventT) {
|
||||
switch (event.eventType) {
|
||||
case fbDebugger.Event.GetStateResponse:
|
||||
this._handle_state_response(
|
||||
event.event as fbDebugger.GetStateResponseT,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_setState(state: EmulationState) {
|
||||
this.state = state;
|
||||
this.stateChangeHandler(this.state);
|
||||
}
|
||||
|
||||
_handle_state_response(response: fbDebugger.GetStateResponseT) {
|
||||
switch (response.state) {
|
||||
case fbDebugger.State.None:
|
||||
this._setState(EmulationState.Stopped);
|
||||
break;
|
||||
|
||||
case fbDebugger.State.Paused:
|
||||
this._setState(EmulationState.Paused);
|
||||
break;
|
||||
|
||||
case fbDebugger.State.Running:
|
||||
this._setState(EmulationState.Running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
page/src/fb/debugger.ts
Normal file
19
page/src/fb/debugger.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
export { DebugEvent, DebugEventT } from './debugger/debug-event.js';
|
||||
export { Event } from './debugger/event.js';
|
||||
export { GetStateRequest, GetStateRequestT } from './debugger/get-state-request.js';
|
||||
export { GetStateResponse, GetStateResponseT } from './debugger/get-state-response.js';
|
||||
export { PauseRequest, PauseRequestT } from './debugger/pause-request.js';
|
||||
export { ReadMemoryRequest, ReadMemoryRequestT } from './debugger/read-memory-request.js';
|
||||
export { ReadMemoryResponse, ReadMemoryResponseT } from './debugger/read-memory-response.js';
|
||||
export { ReadRegisterRequest, ReadRegisterRequestT } from './debugger/read-register-request.js';
|
||||
export { ReadRegisterResponse, ReadRegisterResponseT } from './debugger/read-register-response.js';
|
||||
export { RunRequest, RunRequestT } from './debugger/run-request.js';
|
||||
export { State } from './debugger/state.js';
|
||||
export { WriteMemoryRequest, WriteMemoryRequestT } from './debugger/write-memory-request.js';
|
||||
export { WriteMemoryResponse, WriteMemoryResponseT } from './debugger/write-memory-response.js';
|
||||
export { WriteRegisterRequest, WriteRegisterRequestT } from './debugger/write-register-request.js';
|
||||
export { WriteRegisterResponse, WriteRegisterResponseT } from './debugger/write-register-response.js';
|
||||
119
page/src/fb/debugger/debug-event.ts
Normal file
119
page/src/fb/debugger/debug-event.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { Event, unionToEvent, unionListToEvent } from '../debugger/event.js';
|
||||
import { GetStateRequest, GetStateRequestT } from '../debugger/get-state-request.js';
|
||||
import { GetStateResponse, GetStateResponseT } from '../debugger/get-state-response.js';
|
||||
import { PauseRequest, PauseRequestT } from '../debugger/pause-request.js';
|
||||
import { ReadMemoryRequest, ReadMemoryRequestT } from '../debugger/read-memory-request.js';
|
||||
import { ReadMemoryResponse, ReadMemoryResponseT } from '../debugger/read-memory-response.js';
|
||||
import { ReadRegisterRequest, ReadRegisterRequestT } from '../debugger/read-register-request.js';
|
||||
import { ReadRegisterResponse, ReadRegisterResponseT } from '../debugger/read-register-response.js';
|
||||
import { RunRequest, RunRequestT } from '../debugger/run-request.js';
|
||||
import { WriteMemoryRequest, WriteMemoryRequestT } from '../debugger/write-memory-request.js';
|
||||
import { WriteMemoryResponse, WriteMemoryResponseT } from '../debugger/write-memory-response.js';
|
||||
import { WriteRegisterRequest, WriteRegisterRequestT } from '../debugger/write-register-request.js';
|
||||
import { WriteRegisterResponse, WriteRegisterResponseT } from '../debugger/write-register-response.js';
|
||||
|
||||
|
||||
export class DebugEvent implements flatbuffers.IUnpackableObject<DebugEventT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):DebugEvent {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsDebugEvent(bb:flatbuffers.ByteBuffer, obj?:DebugEvent):DebugEvent {
|
||||
return (obj || new DebugEvent()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsDebugEvent(bb:flatbuffers.ByteBuffer, obj?:DebugEvent):DebugEvent {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new DebugEvent()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
eventType():Event {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint8(this.bb_pos + offset) : Event.NONE;
|
||||
}
|
||||
|
||||
event<T extends flatbuffers.Table>(obj:any):any|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null;
|
||||
}
|
||||
|
||||
static startDebugEvent(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addEventType(builder:flatbuffers.Builder, eventType:Event) {
|
||||
builder.addFieldInt8(0, eventType, Event.NONE);
|
||||
}
|
||||
|
||||
static addEvent(builder:flatbuffers.Builder, eventOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, eventOffset, 0);
|
||||
}
|
||||
|
||||
static endDebugEvent(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static finishDebugEventBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset);
|
||||
}
|
||||
|
||||
static finishSizePrefixedDebugEventBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset, undefined, true);
|
||||
}
|
||||
|
||||
static createDebugEvent(builder:flatbuffers.Builder, eventType:Event, eventOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
DebugEvent.startDebugEvent(builder);
|
||||
DebugEvent.addEventType(builder, eventType);
|
||||
DebugEvent.addEvent(builder, eventOffset);
|
||||
return DebugEvent.endDebugEvent(builder);
|
||||
}
|
||||
|
||||
unpack(): DebugEventT {
|
||||
return new DebugEventT(
|
||||
this.eventType(),
|
||||
(() => {
|
||||
const temp = unionToEvent(this.eventType(), this.event.bind(this));
|
||||
if(temp === null) { return null; }
|
||||
return temp.unpack()
|
||||
})()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: DebugEventT): void {
|
||||
_o.eventType = this.eventType();
|
||||
_o.event = (() => {
|
||||
const temp = unionToEvent(this.eventType(), this.event.bind(this));
|
||||
if(temp === null) { return null; }
|
||||
return temp.unpack()
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
export class DebugEventT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public eventType: Event = Event.NONE,
|
||||
public event: GetStateRequestT|GetStateResponseT|PauseRequestT|ReadMemoryRequestT|ReadMemoryResponseT|ReadRegisterRequestT|ReadRegisterResponseT|RunRequestT|WriteMemoryRequestT|WriteMemoryResponseT|WriteRegisterRequestT|WriteRegisterResponseT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const event = builder.createObjectOffset(this.event);
|
||||
|
||||
return DebugEvent.createDebugEvent(builder,
|
||||
this.eventType,
|
||||
event
|
||||
);
|
||||
}
|
||||
}
|
||||
78
page/src/fb/debugger/event.ts
Normal file
78
page/src/fb/debugger/event.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import { GetStateRequest, GetStateRequestT } from '../debugger/get-state-request.js';
|
||||
import { GetStateResponse, GetStateResponseT } from '../debugger/get-state-response.js';
|
||||
import { PauseRequest, PauseRequestT } from '../debugger/pause-request.js';
|
||||
import { ReadMemoryRequest, ReadMemoryRequestT } from '../debugger/read-memory-request.js';
|
||||
import { ReadMemoryResponse, ReadMemoryResponseT } from '../debugger/read-memory-response.js';
|
||||
import { ReadRegisterRequest, ReadRegisterRequestT } from '../debugger/read-register-request.js';
|
||||
import { ReadRegisterResponse, ReadRegisterResponseT } from '../debugger/read-register-response.js';
|
||||
import { RunRequest, RunRequestT } from '../debugger/run-request.js';
|
||||
import { WriteMemoryRequest, WriteMemoryRequestT } from '../debugger/write-memory-request.js';
|
||||
import { WriteMemoryResponse, WriteMemoryResponseT } from '../debugger/write-memory-response.js';
|
||||
import { WriteRegisterRequest, WriteRegisterRequestT } from '../debugger/write-register-request.js';
|
||||
import { WriteRegisterResponse, WriteRegisterResponseT } from '../debugger/write-register-response.js';
|
||||
|
||||
|
||||
export enum Event {
|
||||
NONE = 0,
|
||||
PauseRequest = 1,
|
||||
RunRequest = 2,
|
||||
GetStateRequest = 3,
|
||||
GetStateResponse = 4,
|
||||
WriteMemoryRequest = 5,
|
||||
WriteMemoryResponse = 6,
|
||||
ReadMemoryRequest = 7,
|
||||
ReadMemoryResponse = 8,
|
||||
WriteRegisterRequest = 9,
|
||||
WriteRegisterResponse = 10,
|
||||
ReadRegisterRequest = 11,
|
||||
ReadRegisterResponse = 12
|
||||
}
|
||||
|
||||
export function unionToEvent(
|
||||
type: Event,
|
||||
accessor: (obj:GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null
|
||||
): GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
switch(Event[type]) {
|
||||
case 'NONE': return null;
|
||||
case 'PauseRequest': return accessor(new PauseRequest())! as PauseRequest;
|
||||
case 'RunRequest': return accessor(new RunRequest())! as RunRequest;
|
||||
case 'GetStateRequest': return accessor(new GetStateRequest())! as GetStateRequest;
|
||||
case 'GetStateResponse': return accessor(new GetStateResponse())! as GetStateResponse;
|
||||
case 'WriteMemoryRequest': return accessor(new WriteMemoryRequest())! as WriteMemoryRequest;
|
||||
case 'WriteMemoryResponse': return accessor(new WriteMemoryResponse())! as WriteMemoryResponse;
|
||||
case 'ReadMemoryRequest': return accessor(new ReadMemoryRequest())! as ReadMemoryRequest;
|
||||
case 'ReadMemoryResponse': return accessor(new ReadMemoryResponse())! as ReadMemoryResponse;
|
||||
case 'WriteRegisterRequest': return accessor(new WriteRegisterRequest())! as WriteRegisterRequest;
|
||||
case 'WriteRegisterResponse': return accessor(new WriteRegisterResponse())! as WriteRegisterResponse;
|
||||
case 'ReadRegisterRequest': return accessor(new ReadRegisterRequest())! as ReadRegisterRequest;
|
||||
case 'ReadRegisterResponse': return accessor(new ReadRegisterResponse())! as ReadRegisterResponse;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function unionListToEvent(
|
||||
type: Event,
|
||||
accessor: (index: number, obj:GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null,
|
||||
index: number
|
||||
): GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
switch(Event[type]) {
|
||||
case 'NONE': return null;
|
||||
case 'PauseRequest': return accessor(index, new PauseRequest())! as PauseRequest;
|
||||
case 'RunRequest': return accessor(index, new RunRequest())! as RunRequest;
|
||||
case 'GetStateRequest': return accessor(index, new GetStateRequest())! as GetStateRequest;
|
||||
case 'GetStateResponse': return accessor(index, new GetStateResponse())! as GetStateResponse;
|
||||
case 'WriteMemoryRequest': return accessor(index, new WriteMemoryRequest())! as WriteMemoryRequest;
|
||||
case 'WriteMemoryResponse': return accessor(index, new WriteMemoryResponse())! as WriteMemoryResponse;
|
||||
case 'ReadMemoryRequest': return accessor(index, new ReadMemoryRequest())! as ReadMemoryRequest;
|
||||
case 'ReadMemoryResponse': return accessor(index, new ReadMemoryResponse())! as ReadMemoryResponse;
|
||||
case 'WriteRegisterRequest': return accessor(index, new WriteRegisterRequest())! as WriteRegisterRequest;
|
||||
case 'WriteRegisterResponse': return accessor(index, new WriteRegisterResponse())! as WriteRegisterResponse;
|
||||
case 'ReadRegisterRequest': return accessor(index, new ReadRegisterRequest())! as ReadRegisterRequest;
|
||||
case 'ReadRegisterResponse': return accessor(index, new ReadRegisterResponse())! as ReadRegisterResponse;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
56
page/src/fb/debugger/get-state-request.ts
Normal file
56
page/src/fb/debugger/get-state-request.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class GetStateRequest implements flatbuffers.IUnpackableObject<GetStateRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GetStateRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGetStateRequest(bb:flatbuffers.ByteBuffer, obj?:GetStateRequest):GetStateRequest {
|
||||
return (obj || new GetStateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGetStateRequest(bb:flatbuffers.ByteBuffer, obj?:GetStateRequest):GetStateRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GetStateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startGetStateRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endGetStateRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGetStateRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
GetStateRequest.startGetStateRequest(builder);
|
||||
return GetStateRequest.endGetStateRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): GetStateRequestT {
|
||||
return new GetStateRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GetStateRequestT): void {}
|
||||
}
|
||||
|
||||
export class GetStateRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return GetStateRequest.createGetStateRequest(builder);
|
||||
}
|
||||
}
|
||||
86
page/src/fb/debugger/get-state-response.ts
Normal file
86
page/src/fb/debugger/get-state-response.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { State } from '../debugger/state.js';
|
||||
|
||||
|
||||
export class GetStateResponse implements flatbuffers.IUnpackableObject<GetStateResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GetStateResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGetStateResponse(bb:flatbuffers.ByteBuffer, obj?:GetStateResponse):GetStateResponse {
|
||||
return (obj || new GetStateResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGetStateResponse(bb:flatbuffers.ByteBuffer, obj?:GetStateResponse):GetStateResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GetStateResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
state():State {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : State.None;
|
||||
}
|
||||
|
||||
mutate_state(value:State):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startGetStateResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addState(builder:flatbuffers.Builder, state:State) {
|
||||
builder.addFieldInt32(0, state, State.None);
|
||||
}
|
||||
|
||||
static endGetStateResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGetStateResponse(builder:flatbuffers.Builder, state:State):flatbuffers.Offset {
|
||||
GetStateResponse.startGetStateResponse(builder);
|
||||
GetStateResponse.addState(builder, state);
|
||||
return GetStateResponse.endGetStateResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): GetStateResponseT {
|
||||
return new GetStateResponseT(
|
||||
this.state()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GetStateResponseT): void {
|
||||
_o.state = this.state();
|
||||
}
|
||||
}
|
||||
|
||||
export class GetStateResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public state: State = State.None
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return GetStateResponse.createGetStateResponse(builder,
|
||||
this.state
|
||||
);
|
||||
}
|
||||
}
|
||||
56
page/src/fb/debugger/pause-request.ts
Normal file
56
page/src/fb/debugger/pause-request.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class PauseRequest implements flatbuffers.IUnpackableObject<PauseRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):PauseRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsPauseRequest(bb:flatbuffers.ByteBuffer, obj?:PauseRequest):PauseRequest {
|
||||
return (obj || new PauseRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsPauseRequest(bb:flatbuffers.ByteBuffer, obj?:PauseRequest):PauseRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new PauseRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startPauseRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endPauseRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createPauseRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
PauseRequest.startPauseRequest(builder);
|
||||
return PauseRequest.endPauseRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): PauseRequestT {
|
||||
return new PauseRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: PauseRequestT): void {}
|
||||
}
|
||||
|
||||
export class PauseRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return PauseRequest.createPauseRequest(builder);
|
||||
}
|
||||
}
|
||||
110
page/src/fb/debugger/read-memory-request.ts
Normal file
110
page/src/fb/debugger/read-memory-request.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ReadMemoryRequest implements flatbuffers.IUnpackableObject<ReadMemoryRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ReadMemoryRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsReadMemoryRequest(bb:flatbuffers.ByteBuffer, obj?:ReadMemoryRequest):ReadMemoryRequest {
|
||||
return (obj || new ReadMemoryRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsReadMemoryRequest(bb:flatbuffers.ByteBuffer, obj?:ReadMemoryRequest):ReadMemoryRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ReadMemoryRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
address():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
mutate_address(value:bigint):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
size():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_size(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startReadMemoryRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addAddress(builder:flatbuffers.Builder, address:bigint) {
|
||||
builder.addFieldInt64(0, address, BigInt('0'));
|
||||
}
|
||||
|
||||
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||
builder.addFieldInt32(1, size, 0);
|
||||
}
|
||||
|
||||
static endReadMemoryRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createReadMemoryRequest(builder:flatbuffers.Builder, address:bigint, size:number):flatbuffers.Offset {
|
||||
ReadMemoryRequest.startReadMemoryRequest(builder);
|
||||
ReadMemoryRequest.addAddress(builder, address);
|
||||
ReadMemoryRequest.addSize(builder, size);
|
||||
return ReadMemoryRequest.endReadMemoryRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): ReadMemoryRequestT {
|
||||
return new ReadMemoryRequestT(
|
||||
this.address(),
|
||||
this.size()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ReadMemoryRequestT): void {
|
||||
_o.address = this.address();
|
||||
_o.size = this.size();
|
||||
}
|
||||
}
|
||||
|
||||
export class ReadMemoryRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public address: bigint = BigInt('0'),
|
||||
public size: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return ReadMemoryRequest.createReadMemoryRequest(builder,
|
||||
this.address,
|
||||
this.size
|
||||
);
|
||||
}
|
||||
}
|
||||
123
page/src/fb/debugger/read-memory-response.ts
Normal file
123
page/src/fb/debugger/read-memory-response.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ReadMemoryResponse implements flatbuffers.IUnpackableObject<ReadMemoryResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ReadMemoryResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsReadMemoryResponse(bb:flatbuffers.ByteBuffer, obj?:ReadMemoryResponse):ReadMemoryResponse {
|
||||
return (obj || new ReadMemoryResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsReadMemoryResponse(bb:flatbuffers.ByteBuffer, obj?:ReadMemoryResponse):ReadMemoryResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ReadMemoryResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
address():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
mutate_address(value:bigint):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
data(index: number):number|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
|
||||
}
|
||||
|
||||
dataLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
dataArray():Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
|
||||
}
|
||||
|
||||
static startReadMemoryResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addAddress(builder:flatbuffers.Builder, address:bigint) {
|
||||
builder.addFieldInt64(0, address, BigInt('0'));
|
||||
}
|
||||
|
||||
static addData(builder:flatbuffers.Builder, dataOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, dataOffset, 0);
|
||||
}
|
||||
|
||||
static createDataVector(builder:flatbuffers.Builder, data:number[]|Uint8Array):flatbuffers.Offset {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startDataVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
}
|
||||
|
||||
static endReadMemoryResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createReadMemoryResponse(builder:flatbuffers.Builder, address:bigint, dataOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ReadMemoryResponse.startReadMemoryResponse(builder);
|
||||
ReadMemoryResponse.addAddress(builder, address);
|
||||
ReadMemoryResponse.addData(builder, dataOffset);
|
||||
return ReadMemoryResponse.endReadMemoryResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ReadMemoryResponseT {
|
||||
return new ReadMemoryResponseT(
|
||||
this.address(),
|
||||
this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ReadMemoryResponseT): void {
|
||||
_o.address = this.address();
|
||||
_o.data = this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class ReadMemoryResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public address: bigint = BigInt('0'),
|
||||
public data: (number)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const data = ReadMemoryResponse.createDataVector(builder, this.data);
|
||||
|
||||
return ReadMemoryResponse.createReadMemoryResponse(builder,
|
||||
this.address,
|
||||
data
|
||||
);
|
||||
}
|
||||
}
|
||||
85
page/src/fb/debugger/read-register-request.ts
Normal file
85
page/src/fb/debugger/read-register-request.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ReadRegisterRequest implements flatbuffers.IUnpackableObject<ReadRegisterRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ReadRegisterRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsReadRegisterRequest(bb:flatbuffers.ByteBuffer, obj?:ReadRegisterRequest):ReadRegisterRequest {
|
||||
return (obj || new ReadRegisterRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsReadRegisterRequest(bb:flatbuffers.ByteBuffer, obj?:ReadRegisterRequest):ReadRegisterRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ReadRegisterRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
register():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_register(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startReadRegisterRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addRegister(builder:flatbuffers.Builder, register:number) {
|
||||
builder.addFieldInt32(0, register, 0);
|
||||
}
|
||||
|
||||
static endReadRegisterRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createReadRegisterRequest(builder:flatbuffers.Builder, register:number):flatbuffers.Offset {
|
||||
ReadRegisterRequest.startReadRegisterRequest(builder);
|
||||
ReadRegisterRequest.addRegister(builder, register);
|
||||
return ReadRegisterRequest.endReadRegisterRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): ReadRegisterRequestT {
|
||||
return new ReadRegisterRequestT(
|
||||
this.register()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ReadRegisterRequestT): void {
|
||||
_o.register = this.register();
|
||||
}
|
||||
}
|
||||
|
||||
export class ReadRegisterRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public register: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return ReadRegisterRequest.createReadRegisterRequest(builder,
|
||||
this.register
|
||||
);
|
||||
}
|
||||
}
|
||||
123
page/src/fb/debugger/read-register-response.ts
Normal file
123
page/src/fb/debugger/read-register-response.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ReadRegisterResponse implements flatbuffers.IUnpackableObject<ReadRegisterResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ReadRegisterResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsReadRegisterResponse(bb:flatbuffers.ByteBuffer, obj?:ReadRegisterResponse):ReadRegisterResponse {
|
||||
return (obj || new ReadRegisterResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsReadRegisterResponse(bb:flatbuffers.ByteBuffer, obj?:ReadRegisterResponse):ReadRegisterResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ReadRegisterResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
register():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_register(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
data(index: number):number|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
|
||||
}
|
||||
|
||||
dataLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
dataArray():Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
|
||||
}
|
||||
|
||||
static startReadRegisterResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addRegister(builder:flatbuffers.Builder, register:number) {
|
||||
builder.addFieldInt32(0, register, 0);
|
||||
}
|
||||
|
||||
static addData(builder:flatbuffers.Builder, dataOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, dataOffset, 0);
|
||||
}
|
||||
|
||||
static createDataVector(builder:flatbuffers.Builder, data:number[]|Uint8Array):flatbuffers.Offset {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startDataVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
}
|
||||
|
||||
static endReadRegisterResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createReadRegisterResponse(builder:flatbuffers.Builder, register:number, dataOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ReadRegisterResponse.startReadRegisterResponse(builder);
|
||||
ReadRegisterResponse.addRegister(builder, register);
|
||||
ReadRegisterResponse.addData(builder, dataOffset);
|
||||
return ReadRegisterResponse.endReadRegisterResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ReadRegisterResponseT {
|
||||
return new ReadRegisterResponseT(
|
||||
this.register(),
|
||||
this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ReadRegisterResponseT): void {
|
||||
_o.register = this.register();
|
||||
_o.data = this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class ReadRegisterResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public register: number = 0,
|
||||
public data: (number)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const data = ReadRegisterResponse.createDataVector(builder, this.data);
|
||||
|
||||
return ReadRegisterResponse.createReadRegisterResponse(builder,
|
||||
this.register,
|
||||
data
|
||||
);
|
||||
}
|
||||
}
|
||||
85
page/src/fb/debugger/run-request.ts
Normal file
85
page/src/fb/debugger/run-request.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class RunRequest implements flatbuffers.IUnpackableObject<RunRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):RunRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsRunRequest(bb:flatbuffers.ByteBuffer, obj?:RunRequest):RunRequest {
|
||||
return (obj || new RunRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsRunRequest(bb:flatbuffers.ByteBuffer, obj?:RunRequest):RunRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new RunRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
singleStep():boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||
}
|
||||
|
||||
mutate_single_step(value:boolean):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeInt8(this.bb_pos + offset, +value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startRunRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addSingleStep(builder:flatbuffers.Builder, singleStep:boolean) {
|
||||
builder.addFieldInt8(0, +singleStep, +false);
|
||||
}
|
||||
|
||||
static endRunRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createRunRequest(builder:flatbuffers.Builder, singleStep:boolean):flatbuffers.Offset {
|
||||
RunRequest.startRunRequest(builder);
|
||||
RunRequest.addSingleStep(builder, singleStep);
|
||||
return RunRequest.endRunRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): RunRequestT {
|
||||
return new RunRequestT(
|
||||
this.singleStep()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: RunRequestT): void {
|
||||
_o.singleStep = this.singleStep();
|
||||
}
|
||||
}
|
||||
|
||||
export class RunRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public singleStep: boolean = false
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return RunRequest.createRunRequest(builder,
|
||||
this.singleStep
|
||||
);
|
||||
}
|
||||
}
|
||||
9
page/src/fb/debugger/state.ts
Normal file
9
page/src/fb/debugger/state.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
export enum State {
|
||||
None = 0,
|
||||
Running = 1,
|
||||
Paused = 2
|
||||
}
|
||||
123
page/src/fb/debugger/write-memory-request.ts
Normal file
123
page/src/fb/debugger/write-memory-request.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class WriteMemoryRequest implements flatbuffers.IUnpackableObject<WriteMemoryRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):WriteMemoryRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsWriteMemoryRequest(bb:flatbuffers.ByteBuffer, obj?:WriteMemoryRequest):WriteMemoryRequest {
|
||||
return (obj || new WriteMemoryRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsWriteMemoryRequest(bb:flatbuffers.ByteBuffer, obj?:WriteMemoryRequest):WriteMemoryRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new WriteMemoryRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
address():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
mutate_address(value:bigint):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
data(index: number):number|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
|
||||
}
|
||||
|
||||
dataLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
dataArray():Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
|
||||
}
|
||||
|
||||
static startWriteMemoryRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addAddress(builder:flatbuffers.Builder, address:bigint) {
|
||||
builder.addFieldInt64(0, address, BigInt('0'));
|
||||
}
|
||||
|
||||
static addData(builder:flatbuffers.Builder, dataOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, dataOffset, 0);
|
||||
}
|
||||
|
||||
static createDataVector(builder:flatbuffers.Builder, data:number[]|Uint8Array):flatbuffers.Offset {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startDataVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
}
|
||||
|
||||
static endWriteMemoryRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createWriteMemoryRequest(builder:flatbuffers.Builder, address:bigint, dataOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
WriteMemoryRequest.startWriteMemoryRequest(builder);
|
||||
WriteMemoryRequest.addAddress(builder, address);
|
||||
WriteMemoryRequest.addData(builder, dataOffset);
|
||||
return WriteMemoryRequest.endWriteMemoryRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): WriteMemoryRequestT {
|
||||
return new WriteMemoryRequestT(
|
||||
this.address(),
|
||||
this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: WriteMemoryRequestT): void {
|
||||
_o.address = this.address();
|
||||
_o.data = this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class WriteMemoryRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public address: bigint = BigInt('0'),
|
||||
public data: (number)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const data = WriteMemoryRequest.createDataVector(builder, this.data);
|
||||
|
||||
return WriteMemoryRequest.createWriteMemoryRequest(builder,
|
||||
this.address,
|
||||
data
|
||||
);
|
||||
}
|
||||
}
|
||||
135
page/src/fb/debugger/write-memory-response.ts
Normal file
135
page/src/fb/debugger/write-memory-response.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class WriteMemoryResponse implements flatbuffers.IUnpackableObject<WriteMemoryResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):WriteMemoryResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsWriteMemoryResponse(bb:flatbuffers.ByteBuffer, obj?:WriteMemoryResponse):WriteMemoryResponse {
|
||||
return (obj || new WriteMemoryResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsWriteMemoryResponse(bb:flatbuffers.ByteBuffer, obj?:WriteMemoryResponse):WriteMemoryResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new WriteMemoryResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
address():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
mutate_address(value:bigint):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
size():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_size(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
success():boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||
}
|
||||
|
||||
mutate_success(value:boolean):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeInt8(this.bb_pos + offset, +value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startWriteMemoryResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(3);
|
||||
}
|
||||
|
||||
static addAddress(builder:flatbuffers.Builder, address:bigint) {
|
||||
builder.addFieldInt64(0, address, BigInt('0'));
|
||||
}
|
||||
|
||||
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||
builder.addFieldInt32(1, size, 0);
|
||||
}
|
||||
|
||||
static addSuccess(builder:flatbuffers.Builder, success:boolean) {
|
||||
builder.addFieldInt8(2, +success, +false);
|
||||
}
|
||||
|
||||
static endWriteMemoryResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createWriteMemoryResponse(builder:flatbuffers.Builder, address:bigint, size:number, success:boolean):flatbuffers.Offset {
|
||||
WriteMemoryResponse.startWriteMemoryResponse(builder);
|
||||
WriteMemoryResponse.addAddress(builder, address);
|
||||
WriteMemoryResponse.addSize(builder, size);
|
||||
WriteMemoryResponse.addSuccess(builder, success);
|
||||
return WriteMemoryResponse.endWriteMemoryResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): WriteMemoryResponseT {
|
||||
return new WriteMemoryResponseT(
|
||||
this.address(),
|
||||
this.size(),
|
||||
this.success()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: WriteMemoryResponseT): void {
|
||||
_o.address = this.address();
|
||||
_o.size = this.size();
|
||||
_o.success = this.success();
|
||||
}
|
||||
}
|
||||
|
||||
export class WriteMemoryResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public address: bigint = BigInt('0'),
|
||||
public size: number = 0,
|
||||
public success: boolean = false
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return WriteMemoryResponse.createWriteMemoryResponse(builder,
|
||||
this.address,
|
||||
this.size,
|
||||
this.success
|
||||
);
|
||||
}
|
||||
}
|
||||
123
page/src/fb/debugger/write-register-request.ts
Normal file
123
page/src/fb/debugger/write-register-request.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class WriteRegisterRequest implements flatbuffers.IUnpackableObject<WriteRegisterRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):WriteRegisterRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsWriteRegisterRequest(bb:flatbuffers.ByteBuffer, obj?:WriteRegisterRequest):WriteRegisterRequest {
|
||||
return (obj || new WriteRegisterRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsWriteRegisterRequest(bb:flatbuffers.ByteBuffer, obj?:WriteRegisterRequest):WriteRegisterRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new WriteRegisterRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
register():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_register(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
data(index: number):number|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index) : 0;
|
||||
}
|
||||
|
||||
dataLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
dataArray():Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
|
||||
}
|
||||
|
||||
static startWriteRegisterRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addRegister(builder:flatbuffers.Builder, register:number) {
|
||||
builder.addFieldInt32(0, register, 0);
|
||||
}
|
||||
|
||||
static addData(builder:flatbuffers.Builder, dataOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, dataOffset, 0);
|
||||
}
|
||||
|
||||
static createDataVector(builder:flatbuffers.Builder, data:number[]|Uint8Array):flatbuffers.Offset {
|
||||
builder.startVector(1, data.length, 1);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addInt8(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startDataVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(1, numElems, 1);
|
||||
}
|
||||
|
||||
static endWriteRegisterRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createWriteRegisterRequest(builder:flatbuffers.Builder, register:number, dataOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
WriteRegisterRequest.startWriteRegisterRequest(builder);
|
||||
WriteRegisterRequest.addRegister(builder, register);
|
||||
WriteRegisterRequest.addData(builder, dataOffset);
|
||||
return WriteRegisterRequest.endWriteRegisterRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): WriteRegisterRequestT {
|
||||
return new WriteRegisterRequestT(
|
||||
this.register(),
|
||||
this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: WriteRegisterRequestT): void {
|
||||
_o.register = this.register();
|
||||
_o.data = this.bb!.createScalarList<number>(this.data.bind(this), this.dataLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class WriteRegisterRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public register: number = 0,
|
||||
public data: (number)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const data = WriteRegisterRequest.createDataVector(builder, this.data);
|
||||
|
||||
return WriteRegisterRequest.createWriteRegisterRequest(builder,
|
||||
this.register,
|
||||
data
|
||||
);
|
||||
}
|
||||
}
|
||||
135
page/src/fb/debugger/write-register-response.ts
Normal file
135
page/src/fb/debugger/write-register-response.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class WriteRegisterResponse implements flatbuffers.IUnpackableObject<WriteRegisterResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):WriteRegisterResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsWriteRegisterResponse(bb:flatbuffers.ByteBuffer, obj?:WriteRegisterResponse):WriteRegisterResponse {
|
||||
return (obj || new WriteRegisterResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsWriteRegisterResponse(bb:flatbuffers.ByteBuffer, obj?:WriteRegisterResponse):WriteRegisterResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new WriteRegisterResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
register():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_register(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
size():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_size(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
success():boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||
}
|
||||
|
||||
mutate_success(value:boolean):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeInt8(this.bb_pos + offset, +value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startWriteRegisterResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(3);
|
||||
}
|
||||
|
||||
static addRegister(builder:flatbuffers.Builder, register:number) {
|
||||
builder.addFieldInt32(0, register, 0);
|
||||
}
|
||||
|
||||
static addSize(builder:flatbuffers.Builder, size:number) {
|
||||
builder.addFieldInt32(1, size, 0);
|
||||
}
|
||||
|
||||
static addSuccess(builder:flatbuffers.Builder, success:boolean) {
|
||||
builder.addFieldInt8(2, +success, +false);
|
||||
}
|
||||
|
||||
static endWriteRegisterResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createWriteRegisterResponse(builder:flatbuffers.Builder, register:number, size:number, success:boolean):flatbuffers.Offset {
|
||||
WriteRegisterResponse.startWriteRegisterResponse(builder);
|
||||
WriteRegisterResponse.addRegister(builder, register);
|
||||
WriteRegisterResponse.addSize(builder, size);
|
||||
WriteRegisterResponse.addSuccess(builder, success);
|
||||
return WriteRegisterResponse.endWriteRegisterResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): WriteRegisterResponseT {
|
||||
return new WriteRegisterResponseT(
|
||||
this.register(),
|
||||
this.size(),
|
||||
this.success()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: WriteRegisterResponseT): void {
|
||||
_o.register = this.register();
|
||||
_o.size = this.size();
|
||||
_o.success = this.success();
|
||||
}
|
||||
}
|
||||
|
||||
export class WriteRegisterResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public register: number = 0,
|
||||
public size: number = 0,
|
||||
public success: boolean = false
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return WriteRegisterResponse.createWriteRegisterResponse(builder,
|
||||
this.register,
|
||||
this.size,
|
||||
this.success
|
||||
);
|
||||
}
|
||||
}
|
||||
5
page/src/fb/events.ts
Normal file
5
page/src/fb/events.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
export * as Debugger from './debugger.js';
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"baseUrl": ".",
|
||||
|
||||
1
src/.clang-format-ignore
Normal file
1
src/.clang-format-ignore
Normal file
@@ -0,0 +1 @@
|
||||
**/*.hxx
|
||||
@@ -9,6 +9,7 @@ momo_targets_set_folder("backends" ${BACKEND_TARGETS})
|
||||
|
||||
if (NOT MOMO_BUILD_AS_LIBRARY)
|
||||
add_subdirectory(analyzer)
|
||||
add_subdirectory(debugger)
|
||||
add_subdirectory(fuzzing-engine)
|
||||
add_subdirectory(fuzzer)
|
||||
add_subdirectory(windows-emulator-test)
|
||||
|
||||
@@ -16,6 +16,7 @@ endif()
|
||||
|
||||
target_link_libraries(analyzer PRIVATE
|
||||
reflect
|
||||
debugger
|
||||
windows-emulator
|
||||
windows-gdb-stub
|
||||
)
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "object_watching.hpp"
|
||||
#include "snapshot.hpp"
|
||||
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
#include <event_handler.hpp>
|
||||
#endif
|
||||
|
||||
#include <utils/interupt_handler.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
@@ -249,6 +253,14 @@ namespace
|
||||
bool run(const analysis_options& options, const std::span<const std::string_view> args)
|
||||
{
|
||||
const auto win_emu = setup_emulator(options, args);
|
||||
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
win_emu->callbacks.on_thread_switch = [&] {
|
||||
debugger::event_context c{.win_emu = *win_emu};
|
||||
debugger::handle_events(c); //
|
||||
};
|
||||
#endif
|
||||
|
||||
win_emu->log.log("Using emulator: %s\n", win_emu->emu().get_name().c_str());
|
||||
|
||||
(void)&watch_system_objects;
|
||||
|
||||
25
src/debugger/CMakeLists.txt
Normal file
25
src/debugger/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
*.hpp
|
||||
*.rc
|
||||
)
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
add_library(debugger ${SRC_FILES})
|
||||
|
||||
momo_assign_source_group(${SRC_FILES})
|
||||
|
||||
target_link_libraries(debugger PRIVATE
|
||||
windows-emulator
|
||||
flatbuffers
|
||||
base64
|
||||
)
|
||||
|
||||
target_include_directories(debugger INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
add_custom_target(generate-flatbuffer
|
||||
DEPENDS flatc
|
||||
COMMAND "$<TARGET_FILE:flatc>" --gen-mutable --gen-object-api --filename-ext hxx --cpp -o "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/events.fbs"
|
||||
COMMAND "$<TARGET_FILE:flatc>" --gen-mutable --gen-object-api --ts -o "${PROJECT_SOURCE_DIR}/page/src/fb" "${CMAKE_CURRENT_LIST_DIR}/events.fbs"
|
||||
)
|
||||
233
src/debugger/event_handler.cpp
Normal file
233
src/debugger/event_handler.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
#include "event_handler.hpp"
|
||||
#include "message_transmitter.hpp"
|
||||
|
||||
#include <base64.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
#include "events_generated.hxx"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace debugger
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::optional<Debugger::DebugEventT> receive_event()
|
||||
{
|
||||
const auto message = receive_message();
|
||||
if (message.empty())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto data = base64::from_base64(message);
|
||||
|
||||
flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(data.data()), data.size());
|
||||
if (!Debugger::VerifyDebugEventBuffer(verifier))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Debugger::DebugEventT e{};
|
||||
Debugger::GetDebugEvent(data.data())->UnPackTo(&e);
|
||||
|
||||
return {std::move(e)};
|
||||
}
|
||||
|
||||
void send_event(const Debugger::DebugEventT& event)
|
||||
{
|
||||
flatbuffers::FlatBufferBuilder fbb{};
|
||||
fbb.Finish(Debugger::DebugEvent::Pack(fbb, &event));
|
||||
|
||||
const std::string_view buffer(reinterpret_cast<const char*>(fbb.GetBufferPointer()), fbb.GetSize());
|
||||
const auto message = base64::to_base64(buffer);
|
||||
|
||||
send_message(message);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(!std::is_same_v<std::remove_cvref_t<T>, Debugger::DebugEventT>)
|
||||
void send_event(T event)
|
||||
{
|
||||
Debugger::DebugEventT e{};
|
||||
e.event.Set(std::move(event));
|
||||
send_event(e);
|
||||
}
|
||||
|
||||
Debugger::State translate_state(const emulation_state state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case emulation_state::paused:
|
||||
return Debugger::State_Paused;
|
||||
|
||||
case emulation_state::none:
|
||||
case emulation_state::running:
|
||||
return Debugger::State_Running;
|
||||
|
||||
default:
|
||||
return Debugger::State_None;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_get_state(const event_context& c)
|
||||
{
|
||||
Debugger::GetStateResponseT response{};
|
||||
response.state = translate_state(c.state);
|
||||
|
||||
send_event(response);
|
||||
}
|
||||
|
||||
void handle_read_memory(const event_context& c, const Debugger::ReadMemoryRequestT& request)
|
||||
{
|
||||
std::vector<uint8_t> buffer{};
|
||||
buffer.resize(request.size);
|
||||
const auto res = c.win_emu.memory.try_read_memory(request.address, buffer.data(), buffer.size());
|
||||
|
||||
Debugger::ReadMemoryResponseT response{};
|
||||
response.address = request.address;
|
||||
|
||||
if (res)
|
||||
{
|
||||
response.data = std::move(buffer);
|
||||
}
|
||||
|
||||
send_event(std::move(response));
|
||||
}
|
||||
|
||||
void handle_write_memory(const event_context& c, const Debugger::WriteMemoryRequestT& request)
|
||||
{
|
||||
bool success{};
|
||||
|
||||
try
|
||||
{
|
||||
c.win_emu.memory.write_memory(request.address, request.data.data(), request.data.size());
|
||||
success = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
Debugger::WriteMemoryResponseT response{};
|
||||
response.address = request.address;
|
||||
response.size = static_cast<uint32_t>(request.data.size());
|
||||
response.success = success;
|
||||
|
||||
send_event(response);
|
||||
}
|
||||
|
||||
void handle_read_register(const event_context& c, const Debugger::ReadRegisterRequestT& request)
|
||||
{
|
||||
std::array<uint8_t, 512> buffer{};
|
||||
const auto res = c.win_emu.emu().read_register(static_cast<x86_register>(request.register_), buffer.data(),
|
||||
buffer.size());
|
||||
|
||||
const auto size = std::min(buffer.size(), res);
|
||||
|
||||
Debugger::ReadRegisterResponseT response{};
|
||||
response.register_ = request.register_;
|
||||
response.data.assign(buffer.data(), buffer.data() + size);
|
||||
|
||||
send_event(std::move(response));
|
||||
}
|
||||
|
||||
void handle_write_register(const event_context& c, const Debugger::WriteRegisterRequestT& request)
|
||||
{
|
||||
bool success{};
|
||||
size_t size = request.data.size();
|
||||
|
||||
try
|
||||
{
|
||||
size = c.win_emu.emu().write_register(static_cast<x86_register>(request.register_), request.data.data(),
|
||||
request.data.size());
|
||||
success = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
Debugger::WriteRegisterResponseT response{};
|
||||
response.register_ = request.register_;
|
||||
response.size = static_cast<uint32_t>(size);
|
||||
response.success = success;
|
||||
|
||||
send_event(response);
|
||||
}
|
||||
|
||||
void handle_event(event_context& c, const Debugger::DebugEventT& e)
|
||||
{
|
||||
switch (e.event.type)
|
||||
{
|
||||
case Debugger::Event_PauseRequest:
|
||||
c.state = emulation_state::paused;
|
||||
break;
|
||||
|
||||
case Debugger::Event_RunRequest:
|
||||
c.state = emulation_state::running;
|
||||
break;
|
||||
|
||||
case Debugger::Event_GetStateRequest:
|
||||
handle_get_state(c);
|
||||
break;
|
||||
|
||||
case Debugger::Event_ReadMemoryRequest:
|
||||
handle_read_memory(c, *e.event.AsReadMemoryRequest());
|
||||
break;
|
||||
|
||||
case Debugger::Event_WriteMemoryRequest:
|
||||
handle_write_memory(c, *e.event.AsWriteMemoryRequest());
|
||||
break;
|
||||
|
||||
case Debugger::Event_ReadRegisterRequest:
|
||||
handle_read_register(c, *e.event.AsReadRegisterRequest());
|
||||
break;
|
||||
|
||||
case Debugger::Event_WriteRegisterRequest:
|
||||
handle_write_register(c, *e.event.AsWriteRegisterRequest());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_events_once(event_context& c)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
suspend_execution(0ms);
|
||||
|
||||
const auto e = receive_event();
|
||||
if (!e.has_value())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
handle_event(c, *e);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_events(event_context& c)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
handle_events_once(c);
|
||||
|
||||
if (c.state != emulation_state::paused)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
suspend_execution(2ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/debugger/event_handler.hpp
Normal file
21
src/debugger/event_handler.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows_emulator.hpp>
|
||||
|
||||
namespace debugger
|
||||
{
|
||||
enum class emulation_state
|
||||
{
|
||||
none,
|
||||
running,
|
||||
paused,
|
||||
};
|
||||
|
||||
struct event_context
|
||||
{
|
||||
windows_emulator& win_emu;
|
||||
emulation_state state{emulation_state::none};
|
||||
};
|
||||
|
||||
void handle_events(event_context& c);
|
||||
}
|
||||
81
src/debugger/events.fbs
Normal file
81
src/debugger/events.fbs
Normal file
@@ -0,0 +1,81 @@
|
||||
namespace Debugger;
|
||||
|
||||
table GetStateRequest {}
|
||||
|
||||
enum State : uint32 {
|
||||
None = 0,
|
||||
Running,
|
||||
Paused,
|
||||
}
|
||||
|
||||
table GetStateResponse {
|
||||
state: State;
|
||||
}
|
||||
|
||||
table PauseRequest {}
|
||||
|
||||
table RunRequest {
|
||||
single_step: bool;
|
||||
}
|
||||
|
||||
table WriteMemoryRequest {
|
||||
address: uint64;
|
||||
data: [ubyte];
|
||||
}
|
||||
|
||||
table WriteMemoryResponse {
|
||||
address: uint64;
|
||||
size: uint32;
|
||||
success: bool;
|
||||
}
|
||||
|
||||
table ReadMemoryRequest {
|
||||
address: uint64;
|
||||
size: uint32;
|
||||
}
|
||||
|
||||
table ReadMemoryResponse {
|
||||
address: uint64;
|
||||
data: [ubyte];
|
||||
}
|
||||
|
||||
table WriteRegisterRequest {
|
||||
register: uint32;
|
||||
data: [ubyte];
|
||||
}
|
||||
|
||||
table WriteRegisterResponse {
|
||||
register: uint32;
|
||||
size: uint32;
|
||||
success: bool;
|
||||
}
|
||||
|
||||
table ReadRegisterRequest {
|
||||
register: uint32;
|
||||
}
|
||||
|
||||
table ReadRegisterResponse {
|
||||
register: uint32;
|
||||
data: [ubyte];
|
||||
}
|
||||
|
||||
union Event {
|
||||
PauseRequest,
|
||||
RunRequest,
|
||||
GetStateRequest,
|
||||
GetStateResponse,
|
||||
WriteMemoryRequest,
|
||||
WriteMemoryResponse,
|
||||
ReadMemoryRequest,
|
||||
ReadMemoryResponse,
|
||||
WriteRegisterRequest,
|
||||
WriteRegisterResponse,
|
||||
ReadRegisterRequest,
|
||||
ReadRegisterResponse,
|
||||
}
|
||||
|
||||
table DebugEvent {
|
||||
event: Event;
|
||||
}
|
||||
|
||||
root_type DebugEvent;
|
||||
2070
src/debugger/events_generated.hxx
Normal file
2070
src/debugger/events_generated.hxx
Normal file
File diff suppressed because it is too large
Load Diff
76
src/debugger/message_transmitter.cpp
Normal file
76
src/debugger/message_transmitter.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "message_transmitter.hpp"
|
||||
#include <platform/compiler.hpp>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <utils/finally.hpp>
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace debugger
|
||||
{
|
||||
void send_message(const std::string& message)
|
||||
{
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
// clang-format off
|
||||
EM_ASM_({
|
||||
handleMessage(UTF8ToString($0));
|
||||
}, message.c_str());
|
||||
// clang-format on
|
||||
#else
|
||||
(void)message;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string receive_message()
|
||||
{
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
// clang-format off
|
||||
auto* ptr = EM_ASM_PTR({
|
||||
var message = getMessageFromQueue();
|
||||
if (!message || message.length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const length = lengthBytesUTF8(message) + 1;
|
||||
const buffer = _malloc(length);
|
||||
stringToUTF8(message, buffer, length);
|
||||
return buffer;
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto _ = utils::finally([&] {
|
||||
free(ptr); //
|
||||
});
|
||||
|
||||
return {reinterpret_cast<const char*>(ptr)};
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void suspend_execution(const std::chrono::milliseconds ms)
|
||||
{
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
emscripten_sleep(static_cast<uint32_t>(ms.count()));
|
||||
#else
|
||||
if (ms > 0ms)
|
||||
{
|
||||
std::this_thread::sleep_for(ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
11
src/debugger/message_transmitter.hpp
Normal file
11
src/debugger/message_transmitter.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace debugger
|
||||
{
|
||||
void suspend_execution(std::chrono::milliseconds ms = std::chrono::milliseconds(0));
|
||||
void send_message(const std::string& message);
|
||||
std::string receive_message();
|
||||
}
|
||||
@@ -34,6 +34,7 @@ struct process_context
|
||||
{
|
||||
utils::optional_function<void(handle h, emulator_thread& thr)> on_create_thread{};
|
||||
utils::optional_function<void(handle h, emulator_thread& thr)> on_thread_terminated{};
|
||||
utils::optional_function<void()> on_thread_switch{};
|
||||
};
|
||||
|
||||
struct atom_entry
|
||||
|
||||
@@ -169,6 +169,7 @@ namespace
|
||||
}
|
||||
|
||||
thread.apc_alertable = false;
|
||||
win_emu.callbacks.on_thread_switch();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user