diff --git a/.gitignore b/.gitignore index 1cbd3af0..5e7c8699 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,7 @@ page/public/analyzer.wasm page/public/debugger.js page/public/debugger.wasm page/public/root.zip +page/public/32/analyzer.js +page/public/32/analyzer.wasm +page/public/64/analyzer.js +page/public/64/analyzer.wasm diff --git a/page/src/components/status-indicator.tsx b/page/src/components/status-indicator.tsx index dc50020e..728d2442 100644 --- a/page/src/components/status-indicator.tsx +++ b/page/src/components/status-indicator.tsx @@ -1,6 +1,6 @@ import { Badge } from "@/components/ui/badge"; import { CircleFill } from "react-bootstrap-icons"; -import { EmulationState as State } from "@/emulator"; +import { EmulationStatus, EmulationState as State } from "@/emulator"; function getStateName(state: State) { switch (state) { diff --git a/page/src/emulator.ts b/page/src/emulator.ts index 91e79fdf..c26b9fa5 100644 --- a/page/src/emulator.ts +++ b/page/src/emulator.ts @@ -13,6 +13,18 @@ export enum EmulationState { Failed, } +export interface EmulationStatus { + executedInstructions: BigInt; + activeThreads: number; +} + +function createDefaultEmulationStatus(): EmulationStatus { + return { + executedInstructions: BigInt(0), + activeThreads: 0, + }; +} + export function isFinalState(state: EmulationState) { switch (state) { case EmulationState.Stopped: @@ -55,10 +67,12 @@ function decodeEvent(data: string) { } type StateChangeHandler = (state: EmulationState) => void; +type StatusUpdateHandler = (status: EmulationStatus) => void; export class Emulator { logHandler: LogHandler; stateChangeHandler: StateChangeHandler; + stautsUpdateHandler: StatusUpdateHandler; terminatePromise: Promise; terminateResolve: (value: number | null) => void; terminateReject: (reason?: any) => void; @@ -66,9 +80,14 @@ export class Emulator { state: EmulationState = EmulationState.Stopped; exit_status: number | null = null; - constructor(logHandler: LogHandler, stateChangeHandler: StateChangeHandler) { + constructor( + logHandler: LogHandler, + stateChangeHandler: StateChangeHandler, + stautsUpdateHandler: StatusUpdateHandler, + ) { this.logHandler = logHandler; this.stateChangeHandler = stateChangeHandler; + this.stautsUpdateHandler = stautsUpdateHandler; this.terminateResolve = () => {}; this.terminateReject = () => {}; this.terminatePromise = new Promise((resolve, reject) => { @@ -84,11 +103,13 @@ export class Emulator { ); this.worker.onerror = this._onError.bind(this); - this.worker.onmessage = this._onMessage.bind(this); + this.worker.onmessage = (e) => queueMicrotask(() => this._onMessage(e)); } async start(settings: Settings, file: string) { this._setState(EmulationState.Running); + this.stautsUpdateHandler(createDefaultEmulationStatus()); + this.worker.postMessage({ message: "run", data: { @@ -197,6 +218,11 @@ export class Emulator { event.event as fbDebugger.ApplicationExitT, ); break; + case fbDebugger.Event.EmulationStatus: + this._handle_emulation_status( + event.event as fbDebugger.EmulationStatusT, + ); + break; } } @@ -209,6 +235,13 @@ export class Emulator { this.exit_status = info.exitStatus; } + _handle_emulation_status(info: fbDebugger.EmulationStatusT) { + this.stautsUpdateHandler({ + activeThreads: info.activeThreads, + executedInstructions: info.executedInstructions, + }); + } + _handle_state_response(response: fbDebugger.GetStateResponseT) { switch (response.state) { case fbDebugger.State.None: diff --git a/page/src/fb/debugger.ts b/page/src/fb/debugger.ts index e181f189..87a9f4a5 100644 --- a/page/src/fb/debugger.ts +++ b/page/src/fb/debugger.ts @@ -4,6 +4,7 @@ export { ApplicationExit, ApplicationExitT } from './debugger/application-exit.js'; export { DebugEvent, DebugEventT } from './debugger/debug-event.js'; +export { EmulationStatus, EmulationStatusT } from './debugger/emulation-status.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'; diff --git a/page/src/fb/debugger/debug-event.ts b/page/src/fb/debugger/debug-event.ts index cb43a59f..bde2cee0 100644 --- a/page/src/fb/debugger/debug-event.ts +++ b/page/src/fb/debugger/debug-event.ts @@ -5,6 +5,7 @@ import * as flatbuffers from 'flatbuffers'; import { ApplicationExit, ApplicationExitT } from '../debugger/application-exit.js'; +import { EmulationStatus, EmulationStatusT } from '../debugger/emulation-status.js'; 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'; @@ -105,7 +106,7 @@ unpackTo(_o: DebugEventT): void { export class DebugEventT implements flatbuffers.IGeneratedObject { constructor( public eventType: Event = Event.NONE, - public event: ApplicationExitT|GetStateRequestT|GetStateResponseT|PauseRequestT|ReadMemoryRequestT|ReadMemoryResponseT|ReadRegisterRequestT|ReadRegisterResponseT|RunRequestT|WriteMemoryRequestT|WriteMemoryResponseT|WriteRegisterRequestT|WriteRegisterResponseT|null = null + public event: ApplicationExitT|EmulationStatusT|GetStateRequestT|GetStateResponseT|PauseRequestT|ReadMemoryRequestT|ReadMemoryResponseT|ReadRegisterRequestT|ReadRegisterResponseT|RunRequestT|WriteMemoryRequestT|WriteMemoryResponseT|WriteRegisterRequestT|WriteRegisterResponseT|null = null ){} diff --git a/page/src/fb/debugger/emulation-status.ts b/page/src/fb/debugger/emulation-status.ts new file mode 100644 index 00000000..1d86bda4 --- /dev/null +++ b/page/src/fb/debugger/emulation-status.ts @@ -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 EmulationStatus implements flatbuffers.IUnpackableObject { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):EmulationStatus { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsEmulationStatus(bb:flatbuffers.ByteBuffer, obj?:EmulationStatus):EmulationStatus { + return (obj || new EmulationStatus()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsEmulationStatus(bb:flatbuffers.ByteBuffer, obj?:EmulationStatus):EmulationStatus { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new EmulationStatus()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +executedInstructions():bigint { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0'); +} + +mutate_executed_instructions(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; +} + +activeThreads():number { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0; +} + +mutate_active_threads(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 startEmulationStatus(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addExecutedInstructions(builder:flatbuffers.Builder, executedInstructions:bigint) { + builder.addFieldInt64(0, executedInstructions, BigInt('0')); +} + +static addActiveThreads(builder:flatbuffers.Builder, activeThreads:number) { + builder.addFieldInt32(1, activeThreads, 0); +} + +static endEmulationStatus(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createEmulationStatus(builder:flatbuffers.Builder, executedInstructions:bigint, activeThreads:number):flatbuffers.Offset { + EmulationStatus.startEmulationStatus(builder); + EmulationStatus.addExecutedInstructions(builder, executedInstructions); + EmulationStatus.addActiveThreads(builder, activeThreads); + return EmulationStatus.endEmulationStatus(builder); +} + +unpack(): EmulationStatusT { + return new EmulationStatusT( + this.executedInstructions(), + this.activeThreads() + ); +} + + +unpackTo(_o: EmulationStatusT): void { + _o.executedInstructions = this.executedInstructions(); + _o.activeThreads = this.activeThreads(); +} +} + +export class EmulationStatusT implements flatbuffers.IGeneratedObject { +constructor( + public executedInstructions: bigint = BigInt('0'), + public activeThreads: number = 0 +){} + + +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return EmulationStatus.createEmulationStatus(builder, + this.executedInstructions, + this.activeThreads + ); +} +} diff --git a/page/src/fb/debugger/event.ts b/page/src/fb/debugger/event.ts index a9b010a5..182a8bc3 100644 --- a/page/src/fb/debugger/event.ts +++ b/page/src/fb/debugger/event.ts @@ -3,6 +3,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ import { ApplicationExit, ApplicationExitT } from '../debugger/application-exit.js'; +import { EmulationStatus, EmulationStatusT } from '../debugger/emulation-status.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'; @@ -31,13 +32,14 @@ export enum Event { WriteRegisterResponse = 10, ReadRegisterRequest = 11, ReadRegisterResponse = 12, - ApplicationExit = 13 + ApplicationExit = 13, + EmulationStatus = 14 } export function unionToEvent( type: Event, - accessor: (obj:ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null -): ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null { + accessor: (obj:ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null +): ApplicationExit|EmulationStatus|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; @@ -53,15 +55,16 @@ export function unionToEvent( case 'ReadRegisterRequest': return accessor(new ReadRegisterRequest())! as ReadRegisterRequest; case 'ReadRegisterResponse': return accessor(new ReadRegisterResponse())! as ReadRegisterResponse; case 'ApplicationExit': return accessor(new ApplicationExit())! as ApplicationExit; + case 'EmulationStatus': return accessor(new EmulationStatus())! as EmulationStatus; default: return null; } } export function unionListToEvent( type: Event, - accessor: (index: number, obj:ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null, + accessor: (index: number, obj:ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null, index: number -): ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null { +): ApplicationExit|EmulationStatus|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; @@ -77,6 +80,7 @@ export function unionListToEvent( case 'ReadRegisterRequest': return accessor(index, new ReadRegisterRequest())! as ReadRegisterRequest; case 'ReadRegisterResponse': return accessor(index, new ReadRegisterResponse())! as ReadRegisterResponse; case 'ApplicationExit': return accessor(index, new ApplicationExit())! as ApplicationExit; + case 'EmulationStatus': return accessor(index, new EmulationStatus())! as EmulationStatus; default: return null; } } diff --git a/page/src/playground.tsx b/page/src/playground.tsx index 8ed9ffc1..b1610fca 100644 --- a/page/src/playground.tsx +++ b/page/src/playground.tsx @@ -23,6 +23,8 @@ import { GearFill, PauseFill, HouseFill, + BarChartSteps, + CpuFill, } from "react-bootstrap-icons"; import { StatusIndicator } from "@/components/status-indicator"; import { Header } from "./Header"; @@ -38,6 +40,7 @@ import { DrawerTitle, } from "@/components/ui/drawer"; import { FilesystemExplorer } from "./filesystem-explorer"; +import { EmulationStatus } from "./emulator"; interface PlaygroundProps {} interface PlaygroundState { @@ -45,6 +48,7 @@ interface PlaygroundState { filesystemPromise: Promise | null; filesystem: Filesystem | null; emulator: Emulator | null; + emulationStatus: EmulationStatus | null; application: string | undefined; drawerOpen: boolean; allowWasm64: boolean; @@ -94,6 +98,10 @@ export class Playground extends React.Component< filesystemPromise: null, filesystem: null, emulator: null, + emulationStatus: { + activeThreads: 5, + executedInstructions: BigInt(1233252643), + }, drawerOpen: false, application: undefined, allowWasm64: false, @@ -124,6 +132,10 @@ export class Playground extends React.Component< location.reload(); } + _onEmulatorStatusChanged(s: EmulationStatus) { + this.setState({ emulationStatus: s }); + } + _onEmulatorStateChanged(s: EmulationState, persistFs: boolean) { if (isFinalState(s) && persistFs) { this.setState({ filesystemPromise: null, filesystem: null }); @@ -208,6 +220,7 @@ export class Playground extends React.Component< const new_emulator = new Emulator( (l) => this.logLines(l), (s) => this._onEmulatorStateChanged(s, persistFs), + (s) => this._onEmulatorStatusChanged(s), ); //new_emulator.onTerminate().then(() => this.setState({ emulator: null })); @@ -320,7 +333,9 @@ export class Playground extends React.Component< )} -
+
+ +
-
- +
+
+ {!this.state.emulationStatus ? ( + <> + ) : ( + <> + {this.state.emulationStatus.activeThreads} + +
+ {this.state.emulationStatus.executedInstructions.toLocaleString()} + + + )} +
+
+ +
diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index f47db0db..9d4bd0ee 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -141,7 +141,7 @@ namespace std::optional exit_status{}; #ifdef OS_EMSCRIPTEN const auto _1 = utils::finally([&] { - debugger::handle_exit(exit_status); // + debugger::handle_exit(win_emu, exit_status); // }); #endif diff --git a/src/debugger/event_handler.cpp b/src/debugger/event_handler.cpp index 6c0e9bc9..8fc26b56 100644 --- a/src/debugger/event_handler.cpp +++ b/src/debugger/event_handler.cpp @@ -1,5 +1,6 @@ #include "event_handler.hpp" #include "message_transmitter.hpp" +#include "windows_emulator.hpp" #include @@ -218,6 +219,8 @@ namespace debugger void handle_events(event_context& c) { + update_emulation_status(c.win_emu); + while (true) { handle_events_once(c); @@ -231,8 +234,18 @@ namespace debugger } } - void handle_exit(std::optional exit_status) + void update_emulation_status(const windows_emulator& win_emu) { + Debugger::EmulationStatusT status{}; + status.executed_instructions = win_emu.get_executed_instructions(); + status.active_threads = static_cast(win_emu.process.threads.size()); + send_event(status); + } + + void handle_exit(const windows_emulator& win_emu, std::optional exit_status) + { + update_emulation_status(win_emu); + Debugger::ApplicationExitT response{}; response.exit_status = exit_status; send_event(response); diff --git a/src/debugger/event_handler.hpp b/src/debugger/event_handler.hpp index bf6e8da3..e3bcff57 100644 --- a/src/debugger/event_handler.hpp +++ b/src/debugger/event_handler.hpp @@ -18,5 +18,6 @@ namespace debugger }; void handle_events(event_context& c); - void handle_exit(std::optional exit_status); + void handle_exit(const windows_emulator& win_emu, std::optional exit_status); + void update_emulation_status(const windows_emulator& win_emu); } diff --git a/src/debugger/events.fbs b/src/debugger/events.fbs index 26275e77..fd4c1d48 100644 --- a/src/debugger/events.fbs +++ b/src/debugger/events.fbs @@ -63,6 +63,11 @@ table ApplicationExit { exit_status: uint32 = null; } +table EmulationStatus { + executed_instructions: uint64; + active_threads: uint32; +} + union Event { PauseRequest, RunRequest, @@ -77,6 +82,7 @@ union Event { ReadRegisterRequest, ReadRegisterResponse, ApplicationExit, + EmulationStatus, } table DebugEvent { diff --git a/src/debugger/events_generated.hxx b/src/debugger/events_generated.hxx index f1010bb8..049b45ba 100644 --- a/src/debugger/events_generated.hxx +++ b/src/debugger/events_generated.hxx @@ -67,6 +67,10 @@ struct ApplicationExit; struct ApplicationExitBuilder; struct ApplicationExitT; +struct EmulationStatus; +struct EmulationStatusBuilder; +struct EmulationStatusT; + struct DebugEvent; struct DebugEventBuilder; struct DebugEventT; @@ -119,11 +123,12 @@ enum Event : uint8_t { Event_ReadRegisterRequest = 11, Event_ReadRegisterResponse = 12, Event_ApplicationExit = 13, + Event_EmulationStatus = 14, Event_MIN = Event_NONE, - Event_MAX = Event_ApplicationExit + Event_MAX = Event_EmulationStatus }; -inline const Event (&EnumValuesEvent())[14] { +inline const Event (&EnumValuesEvent())[15] { static const Event values[] = { Event_NONE, Event_PauseRequest, @@ -138,13 +143,14 @@ inline const Event (&EnumValuesEvent())[14] { Event_WriteRegisterResponse, Event_ReadRegisterRequest, Event_ReadRegisterResponse, - Event_ApplicationExit + Event_ApplicationExit, + Event_EmulationStatus }; return values; } inline const char * const *EnumNamesEvent() { - static const char * const names[15] = { + static const char * const names[16] = { "NONE", "PauseRequest", "RunRequest", @@ -159,13 +165,14 @@ inline const char * const *EnumNamesEvent() { "ReadRegisterRequest", "ReadRegisterResponse", "ApplicationExit", + "EmulationStatus", nullptr }; return names; } inline const char *EnumNameEvent(Event e) { - if (::flatbuffers::IsOutRange(e, Event_NONE, Event_ApplicationExit)) return ""; + if (::flatbuffers::IsOutRange(e, Event_NONE, Event_EmulationStatus)) return ""; const size_t index = static_cast(e); return EnumNamesEvent()[index]; } @@ -226,6 +233,10 @@ template<> struct EventTraits { static const Event enum_value = Event_ApplicationExit; }; +template<> struct EventTraits { + static const Event enum_value = Event_EmulationStatus; +}; + template struct EventUnionTraits { static const Event enum_value = Event_NONE; }; @@ -282,6 +293,10 @@ template<> struct EventUnionTraits { static const Event enum_value = Event_ApplicationExit; }; +template<> struct EventUnionTraits { + static const Event enum_value = Event_EmulationStatus; +}; + struct EventUnion { Event type; void *value; @@ -416,6 +431,14 @@ struct EventUnion { return type == Event_ApplicationExit ? reinterpret_cast(value) : nullptr; } + Debugger::EmulationStatusT *AsEmulationStatus() { + return type == Event_EmulationStatus ? + reinterpret_cast(value) : nullptr; + } + const Debugger::EmulationStatusT *AsEmulationStatus() const { + return type == Event_EmulationStatus ? + reinterpret_cast(value) : nullptr; + } }; bool VerifyEvent(::flatbuffers::Verifier &verifier, const void *obj, Event type); @@ -1278,6 +1301,75 @@ inline ::flatbuffers::Offset CreateApplicationExit( ::flatbuffers::Offset CreateApplicationExit(::flatbuffers::FlatBufferBuilder &_fbb, const ApplicationExitT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct EmulationStatusT : public ::flatbuffers::NativeTable { + typedef EmulationStatus TableType; + uint64_t executed_instructions = 0; + uint32_t active_threads = 0; +}; + +struct EmulationStatus FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef EmulationStatusT NativeTableType; + typedef EmulationStatusBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_EXECUTED_INSTRUCTIONS = 4, + VT_ACTIVE_THREADS = 6 + }; + uint64_t executed_instructions() const { + return GetField(VT_EXECUTED_INSTRUCTIONS, 0); + } + bool mutate_executed_instructions(uint64_t _executed_instructions = 0) { + return SetField(VT_EXECUTED_INSTRUCTIONS, _executed_instructions, 0); + } + uint32_t active_threads() const { + return GetField(VT_ACTIVE_THREADS, 0); + } + bool mutate_active_threads(uint32_t _active_threads = 0) { + return SetField(VT_ACTIVE_THREADS, _active_threads, 0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_EXECUTED_INSTRUCTIONS, 8) && + VerifyField(verifier, VT_ACTIVE_THREADS, 4) && + verifier.EndTable(); + } + EmulationStatusT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EmulationStatusT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const; + static ::flatbuffers::Offset Pack(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EmulationStatusBuilder { + typedef EmulationStatus Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_executed_instructions(uint64_t executed_instructions) { + fbb_.AddElement(EmulationStatus::VT_EXECUTED_INSTRUCTIONS, executed_instructions, 0); + } + void add_active_threads(uint32_t active_threads) { + fbb_.AddElement(EmulationStatus::VT_ACTIVE_THREADS, active_threads, 0); + } + explicit EmulationStatusBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateEmulationStatus( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint64_t executed_instructions = 0, + uint32_t active_threads = 0) { + EmulationStatusBuilder builder_(_fbb); + builder_.add_executed_instructions(executed_instructions); + builder_.add_active_threads(active_threads); + return builder_.Finish(); +} + +::flatbuffers::Offset CreateEmulationStatus(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct DebugEventT : public ::flatbuffers::NativeTable { typedef DebugEvent TableType; Debugger::EventUnion event{}; @@ -1336,6 +1428,9 @@ struct DebugEvent FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const Debugger::ApplicationExit *event_as_ApplicationExit() const { return event_type() == Debugger::Event_ApplicationExit ? static_cast(event()) : nullptr; } + const Debugger::EmulationStatus *event_as_EmulationStatus() const { + return event_type() == Debugger::Event_EmulationStatus ? static_cast(event()) : nullptr; + } void *mutable_event() { return GetPointer(VT_EVENT); } @@ -1403,6 +1498,10 @@ template<> inline const Debugger::ApplicationExit *DebugEvent::event_as inline const Debugger::EmulationStatus *DebugEvent::event_as() const { + return event_as_EmulationStatus(); +} + struct DebugEventBuilder { typedef DebugEvent Table; ::flatbuffers::FlatBufferBuilder &fbb_; @@ -1795,6 +1894,35 @@ inline ::flatbuffers::Offset CreateApplicationExit(::flatbuffer _exit_status); } +inline EmulationStatusT *EmulationStatus::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::unique_ptr(new EmulationStatusT()); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void EmulationStatus::UnPackTo(EmulationStatusT *_o, const ::flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = executed_instructions(); _o->executed_instructions = _e; } + { auto _e = active_threads(); _o->active_threads = _e; } +} + +inline ::flatbuffers::Offset EmulationStatus::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) { + return CreateEmulationStatus(_fbb, _o, _rehasher); +} + +inline ::flatbuffers::Offset CreateEmulationStatus(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const EmulationStatusT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _executed_instructions = _o->executed_instructions; + auto _active_threads = _o->active_threads; + return Debugger::CreateEmulationStatus( + _fbb, + _executed_instructions, + _active_threads); +} + inline DebugEventT *DebugEvent::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const { auto _o = std::unique_ptr(new DebugEventT()); UnPackTo(_o.get(), _resolver); @@ -1881,6 +2009,10 @@ inline bool VerifyEvent(::flatbuffers::Verifier &verifier, const void *obj, Even auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } + case Event_EmulationStatus: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } @@ -1952,6 +2084,10 @@ inline void *EventUnion::UnPack(const void *obj, Event type, const ::flatbuffers auto ptr = reinterpret_cast(obj); return ptr->UnPack(resolver); } + case Event_EmulationStatus: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } default: return nullptr; } } @@ -2011,6 +2147,10 @@ inline ::flatbuffers::Offset EventUnion::Pack(::flatbuffers::FlatBufferBui auto ptr = reinterpret_cast(value); return CreateApplicationExit(_fbb, ptr, _rehasher).Union(); } + case Event_EmulationStatus: { + auto ptr = reinterpret_cast(value); + return CreateEmulationStatus(_fbb, ptr, _rehasher).Union(); + } default: return 0; } } @@ -2069,6 +2209,10 @@ inline EventUnion::EventUnion(const EventUnion &u) : type(u.type), value(nullptr value = new Debugger::ApplicationExitT(*reinterpret_cast(u.value)); break; } + case Event_EmulationStatus: { + value = new Debugger::EmulationStatusT(*reinterpret_cast(u.value)); + break; + } default: break; } @@ -2141,6 +2285,11 @@ inline void EventUnion::Reset() { delete ptr; break; } + case Event_EmulationStatus: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } default: break; } value = nullptr;