@aptre/v86 0.5.0

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.
Files changed (111) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSE.MIT +22 -0
  3. package/Readme.md +237 -0
  4. package/dist/v86.browser.js +26666 -0
  5. package/dist/v86.browser.js.map +7 -0
  6. package/dist/v86.js +26632 -0
  7. package/dist/v86.js.map +7 -0
  8. package/gen/generate_analyzer.ts +512 -0
  9. package/gen/generate_interpreter.ts +522 -0
  10. package/gen/generate_jit.ts +624 -0
  11. package/gen/rust_ast.ts +107 -0
  12. package/gen/util.ts +35 -0
  13. package/gen/x86_table.ts +1836 -0
  14. package/lib/9p.ts +1547 -0
  15. package/lib/filesystem.ts +1879 -0
  16. package/lib/marshall.ts +168 -0
  17. package/lib/softfloat/softfloat.c +32501 -0
  18. package/lib/zstd/zstddeclib.c +13520 -0
  19. package/package.json +75 -0
  20. package/src/acpi.ts +267 -0
  21. package/src/browser/dummy_screen.ts +106 -0
  22. package/src/browser/fake_network.ts +1771 -0
  23. package/src/browser/fetch_network.ts +361 -0
  24. package/src/browser/filestorage.ts +124 -0
  25. package/src/browser/inbrowser_network.ts +57 -0
  26. package/src/browser/keyboard.ts +564 -0
  27. package/src/browser/main.ts +3415 -0
  28. package/src/browser/mouse.ts +255 -0
  29. package/src/browser/network.ts +142 -0
  30. package/src/browser/print_stats.ts +336 -0
  31. package/src/browser/screen.ts +978 -0
  32. package/src/browser/serial.ts +316 -0
  33. package/src/browser/speaker.ts +1223 -0
  34. package/src/browser/starter.ts +1688 -0
  35. package/src/browser/wisp_network.ts +332 -0
  36. package/src/browser/worker_bus.ts +64 -0
  37. package/src/buffer.ts +652 -0
  38. package/src/bus.ts +78 -0
  39. package/src/const.ts +128 -0
  40. package/src/cpu.ts +2891 -0
  41. package/src/dma.ts +474 -0
  42. package/src/elf.ts +251 -0
  43. package/src/floppy.ts +1778 -0
  44. package/src/ide.ts +3455 -0
  45. package/src/io.ts +504 -0
  46. package/src/iso9660.ts +317 -0
  47. package/src/kernel.ts +250 -0
  48. package/src/lib.ts +645 -0
  49. package/src/log.ts +149 -0
  50. package/src/main.ts +199 -0
  51. package/src/ne2k.ts +1589 -0
  52. package/src/pci.ts +815 -0
  53. package/src/pit.ts +406 -0
  54. package/src/ps2.ts +820 -0
  55. package/src/rtc.ts +537 -0
  56. package/src/rust/analysis.rs +101 -0
  57. package/src/rust/codegen.rs +2660 -0
  58. package/src/rust/config.rs +3 -0
  59. package/src/rust/control_flow.rs +425 -0
  60. package/src/rust/cpu/apic.rs +658 -0
  61. package/src/rust/cpu/arith.rs +1207 -0
  62. package/src/rust/cpu/call_indirect.rs +2 -0
  63. package/src/rust/cpu/cpu.rs +4501 -0
  64. package/src/rust/cpu/fpu.rs +923 -0
  65. package/src/rust/cpu/global_pointers.rs +112 -0
  66. package/src/rust/cpu/instructions.rs +2486 -0
  67. package/src/rust/cpu/instructions_0f.rs +5261 -0
  68. package/src/rust/cpu/ioapic.rs +316 -0
  69. package/src/rust/cpu/memory.rs +351 -0
  70. package/src/rust/cpu/misc_instr.rs +613 -0
  71. package/src/rust/cpu/mod.rs +16 -0
  72. package/src/rust/cpu/modrm.rs +133 -0
  73. package/src/rust/cpu/pic.rs +402 -0
  74. package/src/rust/cpu/sse_instr.rs +361 -0
  75. package/src/rust/cpu/string.rs +701 -0
  76. package/src/rust/cpu/vga.rs +175 -0
  77. package/src/rust/cpu_context.rs +69 -0
  78. package/src/rust/dbg.rs +98 -0
  79. package/src/rust/gen/analyzer.rs +3807 -0
  80. package/src/rust/gen/analyzer0f.rs +3992 -0
  81. package/src/rust/gen/interpreter.rs +4447 -0
  82. package/src/rust/gen/interpreter0f.rs +5404 -0
  83. package/src/rust/gen/jit.rs +5080 -0
  84. package/src/rust/gen/jit0f.rs +5547 -0
  85. package/src/rust/gen/mod.rs +14 -0
  86. package/src/rust/jit.rs +2443 -0
  87. package/src/rust/jit_instructions.rs +7881 -0
  88. package/src/rust/js_api.rs +6 -0
  89. package/src/rust/leb.rs +46 -0
  90. package/src/rust/lib.rs +29 -0
  91. package/src/rust/modrm.rs +330 -0
  92. package/src/rust/opstats.rs +249 -0
  93. package/src/rust/page.rs +15 -0
  94. package/src/rust/paging.rs +25 -0
  95. package/src/rust/prefix.rs +15 -0
  96. package/src/rust/profiler.rs +155 -0
  97. package/src/rust/regs.rs +38 -0
  98. package/src/rust/softfloat.rs +286 -0
  99. package/src/rust/state_flags.rs +27 -0
  100. package/src/rust/wasmgen/mod.rs +2 -0
  101. package/src/rust/wasmgen/wasm_builder.rs +1047 -0
  102. package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
  103. package/src/rust/zstd.rs +105 -0
  104. package/src/sb16.ts +1928 -0
  105. package/src/state.ts +359 -0
  106. package/src/uart.ts +472 -0
  107. package/src/vga.ts +2791 -0
  108. package/src/virtio.ts +1756 -0
  109. package/src/virtio_balloon.ts +273 -0
  110. package/src/virtio_console.ts +372 -0
  111. package/src/virtio_net.ts +326 -0
@@ -0,0 +1,316 @@
1
+ import { dbg_assert } from '../log.js'
2
+ import { BusConnector } from '../bus.js'
3
+
4
+ class TextAreaAdapter {
5
+ enabled = true
6
+ text = ''
7
+ text_new_line = false
8
+ last_update = 0
9
+ update_timer: ReturnType<typeof setTimeout> | undefined = undefined
10
+
11
+ protected element: HTMLTextAreaElement
12
+
13
+ private keypress_handler: (e: KeyboardEvent) => void
14
+ private keydown_handler: (e: KeyboardEvent) => void
15
+ private paste_handler: (e: ClipboardEvent) => void
16
+ private window_click_handler: (e: MouseEvent) => void
17
+
18
+ constructor(element: HTMLTextAreaElement) {
19
+ this.element = element
20
+
21
+ this.keypress_handler = (e: KeyboardEvent) => {
22
+ if (!this.may_handle(e)) {
23
+ return
24
+ }
25
+
26
+ const chr = e.which
27
+ this.send_char(chr)
28
+ e.preventDefault()
29
+ }
30
+
31
+ this.keydown_handler = (e: KeyboardEvent) => {
32
+ const chr = e.which
33
+
34
+ if (chr === 8) {
35
+ this.send_char(127)
36
+ e.preventDefault()
37
+ } else if (chr === 9) {
38
+ this.send_char(9)
39
+ e.preventDefault()
40
+ }
41
+ }
42
+
43
+ this.paste_handler = (e: ClipboardEvent) => {
44
+ if (!this.may_handle(e)) {
45
+ return
46
+ }
47
+
48
+ const data = e.clipboardData?.getData('text/plain') || ''
49
+
50
+ for (let i = 0; i < data.length; i++) {
51
+ this.send_char(data.charCodeAt(i))
52
+ }
53
+
54
+ e.preventDefault()
55
+ }
56
+
57
+ this.window_click_handler = (e: MouseEvent) => {
58
+ if (e.target !== element) {
59
+ element.blur()
60
+ }
61
+ }
62
+
63
+ this.init()
64
+ }
65
+
66
+ destroy(): void {
67
+ this.enabled = false
68
+
69
+ this.element.removeEventListener(
70
+ 'keypress',
71
+ this.keypress_handler,
72
+ false,
73
+ )
74
+ this.element.removeEventListener('keydown', this.keydown_handler, false)
75
+ this.element.removeEventListener('paste', this.paste_handler, false)
76
+ window.removeEventListener(
77
+ 'mousedown',
78
+ this.window_click_handler,
79
+ false,
80
+ )
81
+ }
82
+
83
+ init(): void {
84
+ this.destroy()
85
+ this.enabled = true
86
+
87
+ this.element.style.display = 'block'
88
+ this.element.addEventListener('keypress', this.keypress_handler, false)
89
+ this.element.addEventListener('keydown', this.keydown_handler, false)
90
+ this.element.addEventListener('paste', this.paste_handler, false)
91
+ window.addEventListener('mousedown', this.window_click_handler, false)
92
+ }
93
+
94
+ show_char(chr: string): void {
95
+ if (chr === '\x08') {
96
+ this.text = this.text.slice(0, -1)
97
+ this.update()
98
+ } else if (chr === '\r') {
99
+ // do nothing
100
+ } else {
101
+ this.text += chr
102
+
103
+ if (chr === '\n') {
104
+ this.text_new_line = true
105
+ }
106
+
107
+ this.update()
108
+ }
109
+ }
110
+
111
+ update(): void {
112
+ const now = Date.now()
113
+ const delta = now - this.last_update
114
+
115
+ if (delta < 16) {
116
+ if (this.update_timer === undefined) {
117
+ this.update_timer = setTimeout(() => {
118
+ this.update_timer = undefined
119
+ const now = Date.now()
120
+ dbg_assert(now - this.last_update >= 15)
121
+ this.last_update = now
122
+ this.render()
123
+ }, 16 - delta)
124
+ }
125
+ } else {
126
+ if (this.update_timer !== undefined) {
127
+ clearTimeout(this.update_timer)
128
+ this.update_timer = undefined
129
+ }
130
+
131
+ this.last_update = now
132
+ this.render()
133
+ }
134
+ }
135
+
136
+ render(): void {
137
+ this.element.value = this.text
138
+
139
+ if (this.text_new_line) {
140
+ this.text_new_line = false
141
+ this.element.scrollTop = 1e9
142
+ }
143
+ }
144
+
145
+ send_char(_chr_code: number): void {
146
+ // placeholder, overridden by subclasses
147
+ }
148
+
149
+ private may_handle(_e: Event): boolean {
150
+ if (!this.enabled) {
151
+ return false
152
+ }
153
+
154
+ return true
155
+ }
156
+ }
157
+
158
+ export class SerialAdapter extends TextAreaAdapter {
159
+ private bus: BusConnector
160
+
161
+ constructor(element: HTMLTextAreaElement, bus: BusConnector) {
162
+ super(element)
163
+ this.bus = bus
164
+
165
+ bus.register(
166
+ 'serial0-output-byte',
167
+ function (this: SerialAdapter, byte: number) {
168
+ const chr = String.fromCharCode(byte)
169
+ this.show_char(chr)
170
+ },
171
+ this,
172
+ )
173
+ }
174
+
175
+ override send_char(chr_code: number): void {
176
+ this.bus.send('serial0-input', chr_code)
177
+ }
178
+ }
179
+
180
+ export class VirtioConsoleAdapter extends TextAreaAdapter {
181
+ private bus: BusConnector
182
+
183
+ constructor(element: HTMLTextAreaElement, bus: BusConnector) {
184
+ super(element)
185
+ this.bus = bus
186
+
187
+ const decoder = new TextDecoder()
188
+ bus.register(
189
+ 'virtio-console0-output-bytes',
190
+ function (this: VirtioConsoleAdapter, bytes: Uint8Array) {
191
+ for (const chr of decoder.decode(bytes)) {
192
+ this.show_char(chr)
193
+ }
194
+ },
195
+ this,
196
+ )
197
+ }
198
+
199
+ override send_char(chr_code: number): void {
200
+ this.bus.send('virtio-console0-input-bytes', new Uint8Array([chr_code]))
201
+ }
202
+ }
203
+
204
+ class _SerialRecordingAdapter {
205
+ text = ''
206
+
207
+ constructor(bus: BusConnector) {
208
+ bus.register(
209
+ 'serial0-output-byte',
210
+ function (this: _SerialRecordingAdapter, byte: number) {
211
+ const chr = String.fromCharCode(byte)
212
+ this.text += chr
213
+ },
214
+ this,
215
+ )
216
+ }
217
+ }
218
+
219
+ interface XtermTerminal {
220
+ open(element: HTMLElement): void
221
+ write(data: Uint8Array): void
222
+
223
+ onData(callback: (data: string) => void): any
224
+ dispose(): void
225
+ }
226
+
227
+ type XtermConstructor = new (options: any) => XtermTerminal
228
+
229
+ class XtermJSAdapter {
230
+ element: HTMLElement
231
+ term: XtermTerminal
232
+
233
+ on_data_disposable: any
234
+
235
+ constructor(element: HTMLElement, xterm_lib: XtermConstructor) {
236
+ this.element = element
237
+
238
+ this.term = new xterm_lib({
239
+ logLevel: 'off',
240
+ convertEol: 'true',
241
+ })
242
+ }
243
+
244
+ destroy(): void {
245
+ if (this.on_data_disposable) {
246
+ this.on_data_disposable.dispose()
247
+ }
248
+ this.term.dispose()
249
+ }
250
+
251
+ show(): void {
252
+ if (this.term) {
253
+ this.term.open(this.element)
254
+ }
255
+ }
256
+ }
257
+
258
+ export class SerialAdapterXtermJS extends XtermJSAdapter {
259
+ private bus: BusConnector | undefined
260
+
261
+ constructor(
262
+ element: HTMLElement,
263
+ bus: BusConnector,
264
+ xterm_lib: XtermConstructor,
265
+ ) {
266
+ super(element, xterm_lib)
267
+ this.bus = bus
268
+
269
+ bus.register(
270
+ 'serial0-output-byte',
271
+ function (this: SerialAdapterXtermJS, utf8_byte: number) {
272
+ this.term.write(Uint8Array.of(utf8_byte))
273
+ },
274
+ this,
275
+ )
276
+
277
+ const utf8_encoder = new TextEncoder()
278
+ this.on_data_disposable = this.term.onData(function (data_str: string) {
279
+ for (const utf8_byte of utf8_encoder.encode(data_str)) {
280
+ bus.send('serial0-input', utf8_byte)
281
+ }
282
+ })
283
+ }
284
+ }
285
+
286
+ export class VirtioConsoleAdapterXtermJS extends XtermJSAdapter {
287
+ private bus: BusConnector | undefined
288
+
289
+ constructor(
290
+ element: HTMLElement,
291
+ bus: BusConnector,
292
+ xterm_lib: XtermConstructor,
293
+ ) {
294
+ super(element, xterm_lib)
295
+ this.bus = bus
296
+
297
+ bus.register(
298
+ 'virtio-console0-output-bytes',
299
+ function (
300
+ this: VirtioConsoleAdapterXtermJS,
301
+ utf8_bytes: Uint8Array,
302
+ ) {
303
+ this.term.write(utf8_bytes)
304
+ },
305
+ this,
306
+ )
307
+
308
+ const utf8_encoder = new TextEncoder()
309
+ this.on_data_disposable = this.term.onData(function (data_str: string) {
310
+ bus.send(
311
+ 'virtio-console0-input-bytes',
312
+ utf8_encoder.encode(data_str),
313
+ )
314
+ })
315
+ }
316
+ }