@specy/x86 2.0.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -5,14 +5,290 @@ declare function toResourceUrl(source: string | URL): URL;
5
5
  declare function readResourceBytes(source: ResourceSource): Promise<Uint8Array>;
6
6
  declare function defaultResourceUrl(relativePath: string, baseUrl: string): URL;
7
7
  //#endregion
8
+ //#region src/interface.d.ts
9
+ type StatusRegister = {
10
+ name: string;
11
+ value: number;
12
+ prev: number;
13
+ };
14
+ type DiagnosticSeverity = 'error' | 'warning';
15
+ type MonacoError = {
16
+ /** Project-relative source path when checking a virtual Project. */file?: string;
17
+ lineIndex: number;
18
+ column: number;
19
+ line: {
20
+ line: string;
21
+ line_index: number;
22
+ };
23
+ message: string;
24
+ formatted: string; /** A warning still assembles; only an error stops the build. Absent means error. */
25
+ severity?: DiagnosticSeverity; /** The assembler's own name for the warning, such as `label-orphan`. */
26
+ code?: string; /** Help beyond what the assembler said, when this diagnostic has a known explanation. */
27
+ hint?: string;
28
+ };
29
+ type StackFrame = {
30
+ name: string;
31
+ address: bigint;
32
+ destination: bigint;
33
+ sp: bigint;
34
+ line: number;
35
+ file?: string;
36
+ color: string;
37
+ };
38
+ type RegisterHex = [hi: string, lo: string];
39
+ declare enum RegisterSize {
40
+ Byte = 1,
41
+ Word = 2,
42
+ Long = 4,
43
+ Double = 8
44
+ }
45
+ type ExecutionStep = {
46
+ mutations: MutationOperation[];
47
+ pc: number;
48
+ old_ccr: {
49
+ bits: number;
50
+ };
51
+ new_ccr: {
52
+ bits: number;
53
+ };
54
+ line: number;
55
+ file?: string;
56
+ };
57
+ type MutationOperation = {
58
+ type: 'WriteRegister';
59
+ value: {
60
+ register: string;
61
+ old: bigint;
62
+ size: RegisterSize;
63
+ };
64
+ } | {
65
+ type: 'WriteMemory';
66
+ value: {
67
+ address: bigint;
68
+ old: bigint;
69
+ size: RegisterSize;
70
+ };
71
+ } | {
72
+ type: 'WriteMemoryBytes';
73
+ value: {
74
+ address: bigint;
75
+ old: number[];
76
+ };
77
+ } | {
78
+ type: 'PopCallStack';
79
+ value: {
80
+ to: bigint;
81
+ from: bigint;
82
+ };
83
+ } | {
84
+ type: 'PushCallStack';
85
+ value: {
86
+ to: bigint;
87
+ from: bigint;
88
+ };
89
+ } | {
90
+ type: 'Other';
91
+ value: string;
92
+ };
93
+ type EmulatorDecoration = {
94
+ type: 'below-line';
95
+ note?: string;
96
+ belowLine: number;
97
+ md: string;
98
+ };
99
+ type CompilationError = {
100
+ type: 'raw';
101
+ message: string;
102
+ };
103
+ declare enum EmulatorStatus {
104
+ Terminated = 0,
105
+ Running = 1,
106
+ WaitingForInput = 2,
107
+ NotReady = 3
108
+ }
109
+ type Instruction = {
110
+ address: bigint;
111
+ lineNumber: number;
112
+ file?: string;
113
+ size?: number;
114
+ bytes?: Uint8Array;
115
+ code: string;
116
+ };
117
+ type EmulatorConfig<R extends string> = {
118
+ systemSize: RegisterSize;
119
+ registerNames: R[];
120
+ endianness?: 'little' | 'big';
121
+ hiddenRegisters?: R[];
122
+ };
123
+ declare abstract class BaseEmulator<T, R extends string, CompileResult = {
124
+ ok: true;
125
+ } | {
126
+ ok: false;
127
+ errors: CompilationError[];
128
+ report: string;
129
+ }> {
130
+ protected _registerNames: R[];
131
+ protected _systemSize: RegisterSize;
132
+ protected _endianness: 'little' | 'big';
133
+ constructor(options: EmulatorConfig<R>);
134
+ getSystemSize(): RegisterSize;
135
+ getEndianness(): 'little' | 'big';
136
+ getRegisterNames(): R[];
137
+ abstract initialize(undoSize: number): void;
138
+ abstract getCompiledCode(): {
139
+ decorations: EmulatorDecoration[];
140
+ code: string;
141
+ };
142
+ abstract dispose(): void;
143
+ abstract stringifyError(error: unknown): string;
144
+ abstract compile(code: string): Promise<CompileResult>;
145
+ abstract checkCode(code: string): Promise<MonacoError[]>;
146
+ abstract undo(): void;
147
+ abstract canUndo(): boolean;
148
+ abstract step(): Promise<{
149
+ terminated: boolean;
150
+ }>;
151
+ abstract getStatus(): EmulatorStatus;
152
+ abstract writeMemoryBytes(address: bigint, data: Uint8Array): void;
153
+ abstract readMemoryBytes(address: bigint, length: bigint): Uint8Array;
154
+ abstract getNextInstruction(): Instruction | null;
155
+ abstract getUndoHistory(max: number): ExecutionStep[];
156
+ abstract getPc(): bigint;
157
+ abstract getSp(): bigint;
158
+ abstract getFlags(): {
159
+ name: string;
160
+ value: number;
161
+ prev?: number;
162
+ }[];
163
+ abstract getCallStack(): StackFrame[];
164
+ abstract getInstructionAt(address: bigint): Instruction | null;
165
+ abstract getRegisterValues(): bigint[];
166
+ abstract getRegisterValuesRecord(): Record<R, bigint>;
167
+ abstract getRegisterValue(register: R, size?: RegisterSize): bigint;
168
+ abstract setRegisterValue(register: R, value: bigint, size?: RegisterSize): void;
169
+ abstract hasTerminated(): boolean;
170
+ abstract run(limit?: number, breakpoints?: Array<number | {
171
+ path: string;
172
+ line: number;
173
+ }>): Promise<EmulatorStatus>;
174
+ }
175
+ //#endregion
176
+ //#region src/callbacks.d.ts
177
+ type MaybePromise<T> = T | PromiseLike<T>;
178
+ declare function observeCallbackResult(result: MaybePromise<void>): void;
179
+ //#endregion
180
+ //#region src/types.d.ts
181
+ declare const X86_REGISTER_NAMES: readonly ["rax", "rbx", "rcx", "rdx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip"];
182
+ type X86RegisterName = (typeof X86_REGISTER_NAMES)[number];
183
+ declare enum BlinkState {
184
+ NotReady = "NOT_READY",
185
+ Ready = "READY",
186
+ Assembling = "ASSEMBLING",
187
+ Linking = "LINKING",
188
+ ProgramLoaded = "PROGRAM_LOADED",
189
+ ProgramRunning = "PROGRAM_RUNNING",
190
+ ProgramPaused = "PROGRAM_PAUSED",
191
+ ProgramReadlinePause = "PROGRAM_READLINE_PAUSE",
192
+ ProgramStopped = "PROGRAM_STOPPED"
193
+ }
194
+ type StopReasonKind = 'exit' | 'signal' | 'input' | 'limit' | 'breakpoint' | 'load-fail';
195
+ type StopReason = {
196
+ loadFail: boolean;
197
+ exitCode: number;
198
+ details: string;
199
+ kind?: StopReasonKind;
200
+ address?: bigint;
201
+ lineNumber?: number;
202
+ file?: string;
203
+ executedInstructions?: bigint;
204
+ };
205
+ type X86CompilationDiagnostic = {
206
+ line: number;
207
+ error: string; /** Project-relative source path when compiling a virtual Project. */
208
+ file?: string; /** A warning still assembles; only an error stops the build. */
209
+ severity: DiagnosticSeverity; /** The assembler's own name for the warning, such as `label-orphan`. */
210
+ warningClass?: string;
211
+ };
212
+ type X86ProjectFile = string | Uint8Array;
213
+ type X86Project = {
214
+ entry: string;
215
+ files: Readonly<Record<string, X86ProjectFile>>;
216
+ };
217
+ type X86SourceLocation = {
218
+ path: string; /** Zero-based source line. */
219
+ line: number;
220
+ };
221
+ type X86Breakpoint = number | X86SourceLocation;
222
+ /**
223
+ * `diagnostics` carries everything the assembler said, warnings included - a
224
+ * successful build routinely has some, and they are the most useful thing it
225
+ * produces. `errors` is the subset that stopped the build.
226
+ */
227
+ type X86CompileResult = {
228
+ ok: true;
229
+ report: string;
230
+ diagnostics: X86CompilationDiagnostic[];
231
+ } | {
232
+ ok: false;
233
+ errors: X86CompilationDiagnostic[];
234
+ report: string;
235
+ diagnostics: X86CompilationDiagnostic[];
236
+ };
237
+ type X86EmulatorEventMap = {
238
+ stateChange: {
239
+ state: BlinkState;
240
+ oldState: BlinkState;
241
+ };
242
+ stdout: number;
243
+ stderr: number;
244
+ signal: {
245
+ signal: number;
246
+ code: number;
247
+ };
248
+ inputRequest: {
249
+ maxBytes: bigint;
250
+ };
251
+ };
252
+ type X86EmulatorEventName = keyof X86EmulatorEventMap;
253
+ type X86EmulatorEventHandler<T extends X86EmulatorEventName> = (event: X86EmulatorEventMap[T]) => MaybePromise<void>;
254
+ //#endregion
255
+ //#region src/wasm-assembler.d.ts
256
+ /**
257
+ * An assembler that runs as its own WebAssembly module rather than as an x86-64
258
+ * ELF interpreted by blink. Blink costs roughly 1.2s of startup plus 14ms per
259
+ * line of source for NASM; the same work in its own module takes single-digit
260
+ * milliseconds, and produces byte-identical output.
261
+ *
262
+ * The object file comes back as bytes for the caller to stage wherever the
263
+ * linker expects it, so the linker can keep running inside blink unchanged.
264
+ */
265
+ interface WasmAssembler {
266
+ assemble(project: X86Project): Promise<WasmAssemblyResult>;
267
+ }
268
+ type WasmAssemblyResult = {
269
+ /** The assembler's exit status: 0 when it wrote an object file. */status: number; /** What it wrote to stdout, verbatim. */
270
+ stdout: string; /** What it wrote to stderr, verbatim - the diagnostics a parser reads. */
271
+ stderr: string; /** The object file, or null when the assembly failed. */
272
+ object: Uint8Array | null;
273
+ };
274
+ //#endregion
8
275
  //#region src/assemblers.d.ts
9
276
  interface Binary {
10
277
  file: ResourceSource;
11
278
  commands: string;
12
279
  }
13
280
  interface DiagnosticLine {
281
+ file?: string;
14
282
  line: number;
15
283
  error: string;
284
+ /** A warning still assembles; only an error stops the build. */
285
+ severity: DiagnosticSeverity;
286
+ /**
287
+ * NASM's own name for the warning, taken from the `[-w+label-orphan]` tag it
288
+ * appends. It is a stable identifier for the kind of mistake, which is what
289
+ * an explanation can be keyed on.
290
+ */
291
+ warningClass?: string;
16
292
  }
17
293
  type DiagnosticsParser = (assemblerLogs: string) => DiagnosticLine[];
18
294
  interface AssemblerMode {
@@ -21,9 +297,17 @@ interface AssemblerMode {
21
297
  description: string;
22
298
  diagnosticsParser?: DiagnosticsParser;
23
299
  binaries: {
24
- assembler: Binary;
300
+ /**
301
+ * The assembler as an x86-64 ELF for blink to interpret. Absent when
302
+ * `wasmAssembler` is set, which runs the assembler as its own module
303
+ * instead - far faster, but only possible for an assembler written in
304
+ * portable C. Fasm is written in x86 assembly and has no such build.
305
+ */
306
+ assembler?: Binary;
25
307
  linker?: Binary;
26
308
  };
309
+ /** Runs outside blink, and takes precedence over `binaries.assembler`. */
310
+ wasmAssembler?: WasmAssembler;
27
311
  }
28
312
  declare const assemblers: {
29
313
  GNU_trunk: {
@@ -60,15 +344,12 @@ declare const assemblers: {
60
344
  description: string;
61
345
  diagnosticsParser: typeof nasmDiagnostics;
62
346
  binaries: {
63
- assembler: {
64
- file: URL;
65
- commands: string;
66
- };
67
347
  linker: {
68
348
  file: URL;
69
349
  commands: string;
70
350
  };
71
351
  };
352
+ wasmAssembler: WasmAssembler;
72
353
  };
73
354
  };
74
355
  type AssemblerId = keyof typeof assemblers;
@@ -76,64 +357,16 @@ declare const DEFAULT_ASSEMBLER_ID: AssemblerId;
76
357
  declare function nasmDiagnostics(str: string): DiagnosticLine[];
77
358
  declare function gnuDiagnostics(str: string): DiagnosticLine[];
78
359
  declare function fasmDiagnostics(str: string): DiagnosticLine[];
79
- //#endregion
80
- //#region src/callbacks.d.ts
81
- type MaybePromise<T> = T | PromiseLike<T>;
82
- declare function observeCallbackResult(result: MaybePromise<void>): void;
83
- //#endregion
84
- //#region src/types.d.ts
85
- declare const X86_REGISTER_NAMES: readonly ["rax", "rbx", "rcx", "rdx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rip"];
86
- type X86RegisterName = (typeof X86_REGISTER_NAMES)[number];
87
- declare enum BlinkState {
88
- NotReady = "NOT_READY",
89
- Ready = "READY",
90
- Assembling = "ASSEMBLING",
91
- Linking = "LINKING",
92
- ProgramLoaded = "PROGRAM_LOADED",
93
- ProgramRunning = "PROGRAM_RUNNING",
94
- ProgramPaused = "PROGRAM_PAUSED",
95
- ProgramReadlinePause = "PROGRAM_READLINE_PAUSE",
96
- ProgramStopped = "PROGRAM_STOPPED"
97
- }
98
- type StopReasonKind = 'exit' | 'signal' | 'input' | 'limit' | 'breakpoint' | 'load-fail';
99
- type StopReason = {
100
- loadFail: boolean;
101
- exitCode: number;
102
- details: string;
103
- kind?: StopReasonKind;
104
- address?: bigint;
105
- lineNumber?: number;
106
- executedInstructions?: bigint;
107
- };
108
- type X86CompilationDiagnostic = {
109
- line: number;
110
- error: string;
111
- };
112
- type X86CompileResult = {
113
- ok: true;
114
- report: string;
115
- } | {
116
- ok: false;
117
- errors: X86CompilationDiagnostic[];
118
- report: string;
119
- };
120
- type X86EmulatorEventMap = {
121
- stateChange: {
122
- state: BlinkState;
123
- oldState: BlinkState;
124
- };
125
- stdout: number;
126
- stderr: number;
127
- signal: {
128
- signal: number;
129
- code: number;
130
- };
131
- inputRequest: {
132
- maxBytes: bigint;
133
- };
134
- };
135
- type X86EmulatorEventName = keyof X86EmulatorEventMap;
136
- type X86EmulatorEventHandler<T extends X86EmulatorEventName> = (event: X86EmulatorEventMap[T]) => MaybePromise<void>;
360
+ /**
361
+ * The one-based column a diagnostic belongs on. NASM reports a line and no
362
+ * column, but it names the thing it is complaining about: `msg' in "symbol
363
+ * `msg' not defined", `.data' in a section warning. Finding that name in the
364
+ * line turns a whole-line squiggle into one under the mistake itself.
365
+ *
366
+ * Falls back to the first column, which is what the caller would have used
367
+ * anyway, so a message that names nothing findable is no worse off.
368
+ */
369
+ declare function locateDiagnosticColumn(message: string, line: string, warningClass?: string): number;
137
370
  //#endregion
138
371
  //#region src/wasm-types.d.ts
139
372
  type EmscriptenFS = {
@@ -146,6 +379,9 @@ type EmscriptenFS = {
146
379
  readFile(path: string, options?: {
147
380
  encoding?: 'binary' | 'utf8';
148
381
  }): Uint8Array | string;
382
+ mkdirTree(path: string): void;
383
+ unlink(path: string): void;
384
+ chdir(path: string): void;
149
385
  };
150
386
  type BlinkenlibModuleOptions = {
151
387
  noInitialRun?: boolean;
@@ -275,21 +511,62 @@ declare class BlinkRuntime {
275
511
  state: BlinkState;
276
512
  stopReason: StopReason | null;
277
513
  assemblerLogs: string;
278
- assemblerErrors: Array<{
279
- line: number;
280
- error: string;
281
- }>;
514
+ /** The subset of `assemblerDiagnostics` that stopped the build. */
515
+ assemblerErrors: X86CompilationDiagnostic[];
516
+ /** Everything the assembler said, warnings included. */
517
+ assemblerDiagnostics: X86CompilationDiagnostic[];
282
518
  private readonly callbacks;
283
519
  private readonly scheduler;
284
520
  private readonly stateWaiters;
285
521
  private readonly stdinBytes;
286
522
  private sourceMap;
523
+ private sourceProject;
524
+ private assembleOnly;
525
+ private assembledObject;
287
526
  private readonly defaultArgc;
288
527
  private readonly defaultArgv;
289
528
  private constructor();
290
529
  static create(options?: BlinkRuntimeOptions): Promise<BlinkRuntime>;
291
530
  setMode(mode: AssemblerMode | AssemblerId): Promise<void>;
292
531
  compileAssembly(code: string): Promise<X86CompileResult>;
532
+ compileProject(project: X86Project): Promise<X86CompileResult>;
533
+ /**
534
+ * Assembles without linking, for diagnostics. The linked executable is only
535
+ * needed to run or debug a program; a caller that just wants to know what is
536
+ * wrong with the source pays ~450ms for a link it never looks at.
537
+ *
538
+ * A mode with a `wasmAssembler` never touches blink here, so checking also
539
+ * leaves a loaded program - and anything paused in the debugger - alone.
540
+ */
541
+ checkProject(project: X86Project): Promise<X86CompileResult>;
542
+ private checkProjectWithWasmAssembler;
543
+ private buildProject;
544
+ /**
545
+ * The object this build's assembler wrote, for the checks that read it
546
+ * rather than the assembler's own words. Null when the assembly failed, and
547
+ * when the assembler writes an executable directly and never produces one.
548
+ * Read once per build, so a previous build's object can never stand in for
549
+ * one that was never written.
550
+ */
551
+ private takeAssembledObject;
552
+ /**
553
+ * Nothing in the toolchain treats a missing entry point as a failure: NASM
554
+ * has no opinion on it and `ld` only warns, then starts the program at the
555
+ * top of its text segment, where it runs whatever happens to be first. That
556
+ * is the least explicable thing a program can do to someone learning, so it
557
+ * is reported as an error here and the mistake is usually a misspelling.
558
+ */
559
+ private entryPointDiagnostics;
560
+ private assembleInBlink;
561
+ /**
562
+ * Assembles outside blink and hands the object file to the linker inside it,
563
+ * which is where the state machine picks up again as if blink had produced
564
+ * the object itself.
565
+ */
566
+ private assembleWithWasmAssembler;
567
+ private collectAssemblerDiagnostics;
568
+ private emitAssemblerOutput;
569
+ private parseAssemblerDiagnostics;
293
570
  loadElf(data: ArrayBuffer | Uint8Array): void;
294
571
  starti(): void;
295
572
  pauseAtEntry(): void;
@@ -315,8 +592,11 @@ declare class BlinkRuntime {
315
592
  getLastStepInfo(): NativeStepInfo;
316
593
  resolveSymbol(address: bigint): NativeSymbol | null;
317
594
  getSourceLineForAddress(address: bigint): number | null;
595
+ getSourceLocationForAddress(address: bigint): X86SourceLocation | null;
318
596
  getAddressesForSourceLine(lineIndex: number): bigint[];
319
- pauseForBreakpoint(address: bigint, lineNumber: number | undefined): void;
597
+ getAddressesForSourceLocation(location: X86SourceLocation): bigint[];
598
+ getSourceMappedAddresses(): bigint[];
599
+ pauseForBreakpoint(address: bigint, location: X86SourceLocation | undefined): void;
320
600
  pauseForLimit(address: bigint, executedInstructions: bigint): void;
321
601
  resumeAfterStateMutation(): void;
322
602
  private startProgram;
@@ -337,160 +617,18 @@ declare class BlinkRuntime {
337
617
  private tryReadSourceMap;
338
618
  }
339
619
  //#endregion
340
- //#region src/interface.d.ts
341
- type StatusRegister = {
342
- name: string;
343
- value: number;
344
- prev: number;
345
- };
346
- type MonacoError = {
347
- lineIndex: number;
348
- column: number;
349
- line: {
350
- line: string;
351
- line_index: number;
352
- };
353
- message: string;
354
- formatted: string;
355
- };
356
- type StackFrame = {
357
- name: string;
358
- address: bigint;
359
- destination: bigint;
360
- sp: bigint;
361
- line: number;
362
- color: string;
363
- };
364
- type RegisterHex = [hi: string, lo: string];
365
- declare enum RegisterSize {
366
- Byte = 1,
367
- Word = 2,
368
- Long = 4,
369
- Double = 8
370
- }
371
- type ExecutionStep = {
372
- mutations: MutationOperation[];
373
- pc: number;
374
- old_ccr: {
375
- bits: number;
376
- };
377
- new_ccr: {
378
- bits: number;
379
- };
380
- line: number;
381
- };
382
- type MutationOperation = {
383
- type: 'WriteRegister';
384
- value: {
385
- register: string;
386
- old: bigint;
387
- size: RegisterSize;
388
- };
389
- } | {
390
- type: 'WriteMemory';
391
- value: {
392
- address: bigint;
393
- old: bigint;
394
- size: RegisterSize;
395
- };
396
- } | {
397
- type: 'WriteMemoryBytes';
398
- value: {
399
- address: bigint;
400
- old: number[];
401
- };
402
- } | {
403
- type: 'PopCallStack';
404
- value: {
405
- to: bigint;
406
- from: bigint;
407
- };
408
- } | {
409
- type: 'PushCallStack';
410
- value: {
411
- to: bigint;
412
- from: bigint;
413
- };
414
- } | {
415
- type: 'Other';
416
- value: string;
417
- };
418
- type EmulatorDecoration = {
419
- type: 'below-line';
420
- note?: string;
421
- belowLine: number;
422
- md: string;
423
- };
424
- type CompilationError = {
425
- type: 'raw';
426
- message: string;
427
- };
428
- declare enum EmulatorStatus {
429
- Terminated = 0,
430
- Running = 1,
431
- WaitingForInput = 2,
432
- NotReady = 3
433
- }
434
- type Instruction = {
435
- address: bigint;
436
- lineNumber: number;
437
- code: string;
438
- };
439
- type EmulatorConfig<R extends string> = {
440
- systemSize: RegisterSize;
441
- registerNames: R[];
442
- endianness?: 'little' | 'big';
443
- hiddenRegisters?: R[];
444
- };
445
- declare abstract class BaseEmulator<T, R extends string, CompileResult = {
446
- ok: true;
447
- } | {
448
- ok: false;
449
- errors: CompilationError[];
450
- report: string;
451
- }> {
452
- protected _registerNames: R[];
453
- protected _systemSize: RegisterSize;
454
- protected _endianness: 'little' | 'big';
455
- constructor(options: EmulatorConfig<R>);
456
- getSystemSize(): RegisterSize;
457
- getEndianness(): 'little' | 'big';
458
- getRegisterNames(): R[];
459
- abstract initialize(undoSize: number): void;
460
- abstract getCompiledCode(): {
461
- decorations: EmulatorDecoration[];
462
- code: string;
463
- };
464
- abstract dispose(): void;
465
- abstract stringifyError(error: unknown): string;
466
- abstract compile(code: string): Promise<CompileResult>;
467
- abstract checkCode(code: string): Promise<MonacoError[]>;
468
- abstract undo(): void;
469
- abstract canUndo(): boolean;
470
- abstract step(): Promise<{
471
- terminated: boolean;
472
- }>;
473
- abstract getStatus(): EmulatorStatus;
474
- abstract writeMemoryBytes(address: bigint, data: Uint8Array): void;
475
- abstract readMemoryBytes(address: bigint, length: bigint): Uint8Array;
476
- abstract getNextInstruction(): Instruction | null;
477
- abstract getUndoHistory(max: number): ExecutionStep[];
478
- abstract getPc(): bigint;
479
- abstract getSp(): bigint;
480
- abstract getFlags(): {
481
- name: string;
482
- value: number;
483
- prev?: number;
484
- }[];
485
- abstract getCallStack(): StackFrame[];
486
- abstract getInstructionAt(address: bigint): Instruction | null;
487
- abstract getRegisterValues(): bigint[];
488
- abstract getRegisterValuesRecord(): Record<R, bigint>;
489
- abstract getRegisterValue(register: R, size?: RegisterSize): bigint;
490
- abstract setRegisterValue(register: R, value: bigint, size?: RegisterSize): void;
491
- abstract hasTerminated(): boolean;
492
- abstract run(limit?: number, breakpoints?: number[]): Promise<EmulatorStatus>;
493
- }
620
+ //#region src/project.d.ts
621
+ declare const X86_PROJECT_ROOT = "/__x86_project";
622
+ declare function validateX86Project(project: X86Project): void;
623
+ /**
624
+ * Writes a Project into the emulator filesystem and selects the Entry directory as NASM's working
625
+ * directory. NASM consequently owns `%include` and `incbin` resolution, including paths produced by
626
+ * preprocessor macros.
627
+ */
628
+ declare function stageX86Project(fs: EmscriptenFS, project: X86Project): void;
629
+ /** Maps a path emitted by NASM or DWARF back to the exact Project path. */
630
+ declare function x86ProjectSourcePath(sourcePath: string | undefined, project: Pick<X86Project, 'entry' | 'files'>): string;
631
+ declare function x86ProjectText(project: X86Project, path: string): string;
494
632
  //#endregion
495
633
  //#region src/x86-emulator.d.ts
496
634
  type X86EmulatorOptions = Omit<BlinkRuntimeOptions, 'callbacks' | 'mode'> & {
@@ -512,6 +650,7 @@ declare class X86Emulator extends BaseEmulator<BlinkRuntime, X86RegisterName, X8
512
650
  on<T extends X86EmulatorEventName>(eventName: T, handler: X86EmulatorEventHandler<T>): () => void;
513
651
  setMode(mode: AssemblerMode | AssemblerId): Promise<void>;
514
652
  compile(code: string): Promise<X86CompileResult>;
653
+ compileProject(project: X86Project): Promise<X86CompileResult>;
515
654
  loadElf(data: ArrayBuffer | Uint8Array): void;
516
655
  runUntilBlocked(): Promise<EmulatorStatus>;
517
656
  provideInput(line: string): void;
@@ -523,6 +662,12 @@ declare class X86Emulator extends BaseEmulator<BlinkRuntime, X86RegisterName, X8
523
662
  dispose(): void;
524
663
  stringifyError(error: unknown): string;
525
664
  checkCode(code: string): Promise<MonacoError[]>;
665
+ /**
666
+ * Diagnostics only: this assembles but does not link, and for an assembler
667
+ * that runs as its own wasm module it does not touch blink at all, so a
668
+ * loaded or paused program survives a check.
669
+ */
670
+ checkProject(project: X86Project): Promise<MonacoError[]>;
526
671
  undo(): void;
527
672
  canUndo(): boolean;
528
673
  step(): Promise<{
@@ -542,12 +687,14 @@ declare class X86Emulator extends BaseEmulator<BlinkRuntime, X86RegisterName, X8
542
687
  }[];
543
688
  getCallStack(): StackFrame[];
544
689
  getInstructionAt(address: bigint): Instruction | null;
690
+ /** Every instruction address represented in the linked program's DWARF source map. */
691
+ getCompiledInstructions(): Instruction[];
545
692
  getRegisterValues(): bigint[];
546
693
  getRegisterValuesRecord(): Record<X86RegisterName, bigint>;
547
694
  getRegisterValue(register: X86RegisterName, size?: RegisterSize): bigint;
548
695
  setRegisterValue(register: X86RegisterName, value: bigint, size?: RegisterSize): void;
549
696
  hasTerminated(): boolean;
550
- run(limit?: number, breakpoints?: number[]): Promise<EmulatorStatus>;
697
+ run(limit?: number, breakpoints?: X86Breakpoint[]): Promise<EmulatorStatus>;
551
698
  private validateRunLimit;
552
699
  private resolveBreakpointAddresses;
553
700
  private runWithBreakpoints;
@@ -563,5 +710,5 @@ declare class X86Emulator extends BaseEmulator<BlinkRuntime, X86RegisterName, X8
563
710
  }
564
711
  declare function createX86Emulator(options?: X86EmulatorOptions): Promise<X86Emulator>;
565
712
  //#endregion
566
- export { AssemblerId, AssemblerMode, BaseEmulator, Binary, BlinkRunOptions, BlinkRuntime, BlinkRuntimeCallbacks, BlinkRuntimeOptions, BlinkState, BlinkenlibModule, BlinkenlibModuleOptions, CompilationError, DEFAULT_ASSEMBLER_ID, DiagnosticLine, DiagnosticsParser, DisassemblySnapshot, EmscriptenFS, EmulatorConfig, EmulatorDecoration, EmulatorStatus, ExecutionStep, Instruction, MaybePromise, MemoryReadResult, MemoryWriteResult, MonacoError, MutationOperation, NativeControlFlowKind, NativeInstruction, NativeMemoryWrite, NativeRunControls, NativeRunStop, NativeRunStopKind, NativeStepInfo, NativeSymbol, RegisterHex, RegisterSize, RegisterSnapshot, ResourceSource, StackFrame, StatusRegister, StopReason, StopReasonKind, X86CompilationDiagnostic, X86CompileResult, X86Emulator, X86EmulatorEventHandler, X86EmulatorEventMap, X86EmulatorEventName, X86EmulatorOptions, X86RegisterName, X86_REGISTER_NAMES, assemblers, createX86Emulator, defaultResourceUrl, fasmDiagnostics, gnuDiagnostics, isNodeRuntime, nasmDiagnostics, observeCallbackResult, readResourceBytes, toResourceUrl };
713
+ export { AssemblerId, AssemblerMode, BaseEmulator, Binary, BlinkRunOptions, BlinkRuntime, BlinkRuntimeCallbacks, BlinkRuntimeOptions, BlinkState, BlinkenlibModule, BlinkenlibModuleOptions, CompilationError, DEFAULT_ASSEMBLER_ID, DiagnosticLine, DiagnosticSeverity, DiagnosticsParser, DisassemblySnapshot, EmscriptenFS, EmulatorConfig, EmulatorDecoration, EmulatorStatus, ExecutionStep, Instruction, MaybePromise, MemoryReadResult, MemoryWriteResult, MonacoError, MutationOperation, NativeControlFlowKind, NativeInstruction, NativeMemoryWrite, NativeRunControls, NativeRunStop, NativeRunStopKind, NativeStepInfo, NativeSymbol, RegisterHex, RegisterSize, RegisterSnapshot, ResourceSource, StackFrame, StatusRegister, StopReason, StopReasonKind, X86Breakpoint, X86CompilationDiagnostic, X86CompileResult, X86Emulator, X86EmulatorEventHandler, X86EmulatorEventMap, X86EmulatorEventName, X86EmulatorOptions, X86Project, X86ProjectFile, X86RegisterName, X86SourceLocation, X86_PROJECT_ROOT, X86_REGISTER_NAMES, assemblers, createX86Emulator, defaultResourceUrl, fasmDiagnostics, gnuDiagnostics, isNodeRuntime, locateDiagnosticColumn, nasmDiagnostics, observeCallbackResult, readResourceBytes, stageX86Project, toResourceUrl, validateX86Project, x86ProjectSourcePath, x86ProjectText };
567
714
  //# sourceMappingURL=index.d.mts.map