wasm-idle 0.3.2 → 0.4.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.
- package/README.md +4 -2
- package/dist/clang/app.d.ts +2 -1
- package/dist/clang/app.js +149 -132
- package/dist/clang/index.js +2 -2
- package/dist/debug/expression.js +135 -19
- package/dist/debug/index.d.ts +1 -1
- package/dist/debug/index.js +1 -1
- package/dist/debug/language/index.d.ts +1 -0
- package/dist/debug/language/index.js +1 -0
- package/dist/debug/language/python.d.ts +2 -0
- package/dist/debug/language/python.js +14 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/playground/clang.d.ts +5 -2
- package/dist/playground/clang.js +44 -18
- package/dist/playground/index.d.ts +2 -1
- package/dist/playground/index.js +7 -1
- package/dist/playground/java.d.ts +28 -0
- package/dist/playground/java.js +135 -0
- package/dist/playground/javaStdin.d.ts +8 -0
- package/dist/playground/javaStdin.js +90 -0
- package/dist/playground/options.d.ts +10 -0
- package/dist/playground/python.d.ts +15 -5
- package/dist/playground/python.js +98 -21
- package/dist/playground/sandbox.d.ts +3 -1
- package/dist/playground/stdinBuffer.d.ts +7 -0
- package/dist/playground/stdinBuffer.js +100 -0
- package/dist/playground/teavmConfig.d.ts +3 -0
- package/dist/playground/teavmConfig.js +14 -0
- package/dist/playground/worker/clang.js +2 -20
- package/dist/playground/worker/java.d.ts +1 -0
- package/dist/playground/worker/java.js +248 -0
- package/dist/playground/worker/python.js +253 -27
- package/dist/terminal/Terminal.svelte +41 -11
- package/dist/terminal/Terminal.svelte.d.ts +2 -1
- package/dist/terminal/types.d.ts +3 -2
- package/package.json +1 -1
|
@@ -9,20 +9,23 @@ declare class Clang implements Sandbox {
|
|
|
9
9
|
buffer: SharedArrayBuffer;
|
|
10
10
|
debugBuffer: SharedArrayBuffer;
|
|
11
11
|
interruptBuffer: SharedArrayBuffer;
|
|
12
|
-
|
|
12
|
+
pendingInput: string[];
|
|
13
13
|
begin: number;
|
|
14
14
|
elapse: number;
|
|
15
15
|
uid: number;
|
|
16
16
|
log: boolean;
|
|
17
|
+
waitingForInput: boolean;
|
|
18
|
+
pendingEof: boolean;
|
|
17
19
|
exit: boolean;
|
|
18
20
|
load(path: string, code?: string, log?: boolean, args?: string[], _options?: SandboxExecutionOptions): Promise<void>;
|
|
19
21
|
write(input: string): void;
|
|
20
|
-
_write(input: string): void;
|
|
21
22
|
eof(): void;
|
|
23
|
+
private flushPendingInput;
|
|
22
24
|
run(code: string, prepare: boolean, log?: boolean, prog?: Writable<number> | {
|
|
23
25
|
set?: (value: number) => void;
|
|
24
26
|
}, args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
|
|
25
27
|
debugCommand(command: DebugCommand): void;
|
|
28
|
+
kill(): void;
|
|
26
29
|
terminate(): void;
|
|
27
30
|
clear(): Promise<void>;
|
|
28
31
|
}
|
package/dist/playground/clang.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
|
|
1
2
|
class Clang {
|
|
2
3
|
ts = Date.now();
|
|
3
4
|
output = null;
|
|
@@ -6,16 +7,20 @@ class Clang {
|
|
|
6
7
|
buffer = new SharedArrayBuffer(1024);
|
|
7
8
|
debugBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4);
|
|
8
9
|
interruptBuffer = new SharedArrayBuffer(1);
|
|
9
|
-
|
|
10
|
+
pendingInput = [];
|
|
10
11
|
begin = 0;
|
|
11
12
|
elapse = 0;
|
|
12
13
|
uid = 0;
|
|
13
14
|
log = true;
|
|
15
|
+
waitingForInput = false;
|
|
16
|
+
pendingEof = false;
|
|
14
17
|
exit = true;
|
|
15
18
|
load(path, code = '', log = true, args = [], _options = {}) {
|
|
16
19
|
return new Promise(async (resolve) => {
|
|
17
20
|
this.log = log;
|
|
18
|
-
this.
|
|
21
|
+
this.pendingInput = [];
|
|
22
|
+
this.waitingForInput = false;
|
|
23
|
+
this.pendingEof = false;
|
|
19
24
|
if (!this.worker) {
|
|
20
25
|
this.worker = new (await import('./worker/clang?worker')).default();
|
|
21
26
|
this.worker.onmessage = () => resolve();
|
|
@@ -28,19 +33,27 @@ class Clang {
|
|
|
28
33
|
});
|
|
29
34
|
}
|
|
30
35
|
write(input) {
|
|
31
|
-
this.
|
|
36
|
+
this.pendingInput.push(input);
|
|
37
|
+
this.pendingEof = false;
|
|
38
|
+
this.flushPendingInput();
|
|
32
39
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
eof() {
|
|
41
|
+
this.pendingEof = true;
|
|
42
|
+
this.flushPendingInput();
|
|
43
|
+
}
|
|
44
|
+
flushPendingInput() {
|
|
45
|
+
if (!this.waitingForInput)
|
|
46
|
+
return;
|
|
47
|
+
if (flushQueuedStdin(this.pendingInput, this.buffer)) {
|
|
48
|
+
this.waitingForInput = false;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (this.pendingEof) {
|
|
52
|
+
flushBufferedEof(this.buffer);
|
|
53
|
+
this.pendingEof = false;
|
|
54
|
+
this.waitingForInput = false;
|
|
55
|
+
}
|
|
42
56
|
}
|
|
43
|
-
eof() { }
|
|
44
57
|
run(code, prepare, log = this.log, prog, args = [], options = {}) {
|
|
45
58
|
this.exit = false;
|
|
46
59
|
return new Promise(async (resolve, reject) => {
|
|
@@ -53,8 +66,10 @@ class Clang {
|
|
|
53
66
|
if (_uid !== this.uid)
|
|
54
67
|
return (this.worker.onmessage = null);
|
|
55
68
|
const { id, output, results, log, error, buffer, progress, debugEvent } = event.data;
|
|
56
|
-
if (buffer
|
|
57
|
-
this.
|
|
69
|
+
if (buffer) {
|
|
70
|
+
this.waitingForInput = true;
|
|
71
|
+
this.flushPendingInput();
|
|
72
|
+
}
|
|
58
73
|
if (output)
|
|
59
74
|
this.output(output);
|
|
60
75
|
if (debugEvent)
|
|
@@ -62,6 +77,8 @@ class Clang {
|
|
|
62
77
|
if (results) {
|
|
63
78
|
this.elapse = Date.now() - this.begin;
|
|
64
79
|
this.exit = true;
|
|
80
|
+
this.waitingForInput = false;
|
|
81
|
+
this.pendingEof = false;
|
|
65
82
|
this.ondebug?.({ type: 'stop' });
|
|
66
83
|
resolve(results);
|
|
67
84
|
}
|
|
@@ -69,6 +86,10 @@ class Clang {
|
|
|
69
86
|
console.log(log);
|
|
70
87
|
if (error) {
|
|
71
88
|
this.elapse = Date.now() - this.begin;
|
|
89
|
+
this.waitingForInput = false;
|
|
90
|
+
this.pendingEof = false;
|
|
91
|
+
this.exit = true;
|
|
92
|
+
this.ondebug?.({ type: 'stop' });
|
|
72
93
|
reject(error);
|
|
73
94
|
}
|
|
74
95
|
if (progress)
|
|
@@ -99,7 +120,11 @@ class Clang {
|
|
|
99
120
|
Atomics.notify(control, 0);
|
|
100
121
|
this.ondebug?.({ type: 'resume', command });
|
|
101
122
|
}
|
|
123
|
+
kill() {
|
|
124
|
+
this.terminate();
|
|
125
|
+
}
|
|
102
126
|
terminate() {
|
|
127
|
+
this.pendingEof = false;
|
|
103
128
|
new Uint8Array(this.interruptBuffer)[0] = 2;
|
|
104
129
|
const control = new Int32Array(this.debugBuffer);
|
|
105
130
|
Atomics.add(control, 0, 1);
|
|
@@ -107,11 +132,12 @@ class Clang {
|
|
|
107
132
|
}
|
|
108
133
|
async clear() {
|
|
109
134
|
this.terminate();
|
|
110
|
-
this.
|
|
135
|
+
this.pendingInput = [];
|
|
136
|
+
this.waitingForInput = false;
|
|
137
|
+
this.pendingEof = false;
|
|
111
138
|
if (this.worker)
|
|
112
139
|
this.worker.onmessage = null;
|
|
113
|
-
|
|
114
|
-
buffer.fill(0);
|
|
140
|
+
resetBufferedStdin(this.buffer);
|
|
115
141
|
const debugBuffer = new Int32Array(this.debugBuffer);
|
|
116
142
|
debugBuffer.fill(0);
|
|
117
143
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Clang from './clang';
|
|
2
|
+
import Java from './java';
|
|
2
3
|
import Python from './python';
|
|
3
4
|
import type { Sandbox } from './sandbox';
|
|
4
5
|
export declare const supportedLanguages: string[];
|
|
5
|
-
export default function load(language: string): Promise<Sandbox | Clang | Python>;
|
|
6
|
+
export default function load(language: string): Promise<Sandbox | Clang | Java | Python>;
|
package/dist/playground/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import Clang from './clang';
|
|
2
|
+
import Java from './java';
|
|
2
3
|
import Python from './python';
|
|
3
4
|
const sandboxCache = {};
|
|
4
|
-
export const supportedLanguages = ['PYTHON3', 'PYPY3', 'C', 'CPP'];
|
|
5
|
+
export const supportedLanguages = ['PYTHON3', 'PYPY3', 'C', 'CPP', 'JAVA'];
|
|
5
6
|
export default async function load(language) {
|
|
6
7
|
if (sandboxCache[language])
|
|
7
8
|
return sandboxCache[language];
|
|
@@ -16,6 +17,9 @@ export default async function load(language) {
|
|
|
16
17
|
case 'CPP':
|
|
17
18
|
sandbox = new Clang();
|
|
18
19
|
break;
|
|
20
|
+
case 'JAVA':
|
|
21
|
+
sandbox = new Java();
|
|
22
|
+
break;
|
|
19
23
|
default:
|
|
20
24
|
throw new Error(`Unsupported language: ${language}`);
|
|
21
25
|
}
|
|
@@ -31,6 +35,8 @@ export default async function load(language) {
|
|
|
31
35
|
sandboxCache['C'] = sandbox;
|
|
32
36
|
if (language === 'CPP')
|
|
33
37
|
sandboxCache['CPP'] = sandbox;
|
|
38
|
+
if (language === 'JAVA')
|
|
39
|
+
sandboxCache['JAVA'] = sandbox;
|
|
34
40
|
}
|
|
35
41
|
return sandbox;
|
|
36
42
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CompilerDiagnostic, SandboxExecutionOptions } from './options';
|
|
2
|
+
import type { Sandbox } from './sandbox';
|
|
3
|
+
declare class Java implements Sandbox {
|
|
4
|
+
output: any;
|
|
5
|
+
worker?: Worker;
|
|
6
|
+
buffer: SharedArrayBuffer;
|
|
7
|
+
pendingInput: string[];
|
|
8
|
+
begin: number;
|
|
9
|
+
elapse: number;
|
|
10
|
+
uid: number;
|
|
11
|
+
exit: boolean;
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
activeReject: ((reason: string) => void) | null;
|
|
14
|
+
oncompilerdiagnostic?: (diagnostic: CompilerDiagnostic) => void;
|
|
15
|
+
waitingForInput: boolean;
|
|
16
|
+
pendingEof: boolean;
|
|
17
|
+
load(path: string, _code?: string, _log?: boolean, _args?: string[], _options?: SandboxExecutionOptions): Promise<void>;
|
|
18
|
+
write(input: string): void;
|
|
19
|
+
eof(): void;
|
|
20
|
+
private flushPendingInput;
|
|
21
|
+
run(code: string, prepare: boolean, _log?: boolean, _prog?: {
|
|
22
|
+
set?: (value: number) => void;
|
|
23
|
+
} | import('svelte/store').Writable<number>, args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
|
|
24
|
+
kill(): void;
|
|
25
|
+
terminate(): void;
|
|
26
|
+
clear(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export default Java;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
|
|
2
|
+
import { resolveTeaVmBaseUrl } from './teavmConfig';
|
|
3
|
+
class Java {
|
|
4
|
+
output = null;
|
|
5
|
+
worker = null;
|
|
6
|
+
buffer = new SharedArrayBuffer(1024);
|
|
7
|
+
pendingInput = [];
|
|
8
|
+
begin = 0;
|
|
9
|
+
elapse = 0;
|
|
10
|
+
uid = 0;
|
|
11
|
+
exit = true;
|
|
12
|
+
baseUrl = '';
|
|
13
|
+
activeReject = null;
|
|
14
|
+
oncompilerdiagnostic;
|
|
15
|
+
waitingForInput = false;
|
|
16
|
+
pendingEof = false;
|
|
17
|
+
load(path, _code = '', _log = true, _args = [], _options = {}) {
|
|
18
|
+
return new Promise(async (resolve, reject) => {
|
|
19
|
+
this.pendingInput = [];
|
|
20
|
+
this.waitingForInput = false;
|
|
21
|
+
this.pendingEof = false;
|
|
22
|
+
this.baseUrl = resolveTeaVmBaseUrl(path, typeof window !== 'undefined' ? window.location.href : '');
|
|
23
|
+
if (!this.worker) {
|
|
24
|
+
this.worker = new (await import('./worker/java?worker')).default();
|
|
25
|
+
this.worker.onmessage = (event) => {
|
|
26
|
+
if (event.data?.load)
|
|
27
|
+
resolve();
|
|
28
|
+
if (event.data?.error)
|
|
29
|
+
reject(event.data.error);
|
|
30
|
+
};
|
|
31
|
+
this.worker.postMessage({ load: true, baseUrl: this.baseUrl });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
resolve();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
write(input) {
|
|
39
|
+
this.pendingInput.push(input);
|
|
40
|
+
this.pendingEof = false;
|
|
41
|
+
this.flushPendingInput();
|
|
42
|
+
}
|
|
43
|
+
eof() {
|
|
44
|
+
this.pendingEof = true;
|
|
45
|
+
this.flushPendingInput();
|
|
46
|
+
}
|
|
47
|
+
flushPendingInput() {
|
|
48
|
+
if (!this.waitingForInput)
|
|
49
|
+
return;
|
|
50
|
+
if (flushQueuedStdin(this.pendingInput, this.buffer)) {
|
|
51
|
+
this.waitingForInput = false;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (this.pendingEof) {
|
|
55
|
+
flushBufferedEof(this.buffer);
|
|
56
|
+
this.pendingEof = false;
|
|
57
|
+
this.waitingForInput = false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
run(code, prepare, _log = true, _prog, args = [], options = {}) {
|
|
61
|
+
this.exit = false;
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
if (!this.worker)
|
|
64
|
+
return reject('Worker not loaded');
|
|
65
|
+
const _uid = ++this.uid;
|
|
66
|
+
this.activeReject = reject;
|
|
67
|
+
const handler = (event) => {
|
|
68
|
+
if (!this.worker)
|
|
69
|
+
return reject('Worker not loaded');
|
|
70
|
+
if (_uid !== this.uid)
|
|
71
|
+
return (this.worker.onmessage = null);
|
|
72
|
+
const { output, results, error, buffer, diagnostic } = event.data;
|
|
73
|
+
if (buffer) {
|
|
74
|
+
this.waitingForInput = true;
|
|
75
|
+
this.flushPendingInput();
|
|
76
|
+
}
|
|
77
|
+
if (output)
|
|
78
|
+
this.output(output);
|
|
79
|
+
if (diagnostic)
|
|
80
|
+
this.oncompilerdiagnostic?.(diagnostic);
|
|
81
|
+
if (results) {
|
|
82
|
+
this.elapse = Date.now() - this.begin;
|
|
83
|
+
this.exit = true;
|
|
84
|
+
this.waitingForInput = false;
|
|
85
|
+
this.pendingEof = false;
|
|
86
|
+
this.activeReject = null;
|
|
87
|
+
resolve(results);
|
|
88
|
+
}
|
|
89
|
+
if (error) {
|
|
90
|
+
this.elapse = Date.now() - this.begin;
|
|
91
|
+
this.exit = true;
|
|
92
|
+
this.waitingForInput = false;
|
|
93
|
+
this.pendingEof = false;
|
|
94
|
+
this.activeReject = null;
|
|
95
|
+
reject(error);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
this.worker.onmessage = handler;
|
|
99
|
+
this.begin = Date.now();
|
|
100
|
+
this.worker.postMessage({
|
|
101
|
+
code,
|
|
102
|
+
prepare,
|
|
103
|
+
buffer: this.buffer,
|
|
104
|
+
args,
|
|
105
|
+
stdin: options.stdin || '',
|
|
106
|
+
baseUrl: this.baseUrl
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
kill() {
|
|
111
|
+
this.terminate();
|
|
112
|
+
}
|
|
113
|
+
terminate() {
|
|
114
|
+
this.activeReject?.('Process terminated');
|
|
115
|
+
this.activeReject = null;
|
|
116
|
+
this.waitingForInput = false;
|
|
117
|
+
this.pendingEof = false;
|
|
118
|
+
this.uid += 1;
|
|
119
|
+
this.worker?.terminate?.();
|
|
120
|
+
delete this.worker;
|
|
121
|
+
this.exit = true;
|
|
122
|
+
}
|
|
123
|
+
async clear() {
|
|
124
|
+
this.pendingInput = [];
|
|
125
|
+
this.waitingForInput = false;
|
|
126
|
+
this.pendingEof = false;
|
|
127
|
+
if (this.worker)
|
|
128
|
+
this.worker.onmessage = null;
|
|
129
|
+
resetBufferedStdin(this.buffer);
|
|
130
|
+
if (!this.exit) {
|
|
131
|
+
this.terminate();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export default Java;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface PreparedJavaStdinInjection {
|
|
2
|
+
usesStdin: boolean;
|
|
3
|
+
stdinCacheKey: string;
|
|
4
|
+
transformedCode: string;
|
|
5
|
+
helperSourcePath: string | null;
|
|
6
|
+
helperSource: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare const prepareJavaStdinInjection: (code: string, stdin: string) => PreparedJavaStdinInjection;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const JAVA_STDIN_HELPER_CLASS = 'WasmIdleStdin';
|
|
2
|
+
export const prepareJavaStdinInjection = (code, stdin) => {
|
|
3
|
+
const usesStdin = code.includes('System.in');
|
|
4
|
+
if (!usesStdin) {
|
|
5
|
+
return {
|
|
6
|
+
usesStdin: false,
|
|
7
|
+
stdinCacheKey: '',
|
|
8
|
+
transformedCode: code,
|
|
9
|
+
helperSourcePath: null,
|
|
10
|
+
helperSource: null
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const packageMatch = code.match(/^\s*package\s+([A-Za-z_][\w.]*)\s*;/m);
|
|
14
|
+
const packageName = packageMatch?.[1] || '';
|
|
15
|
+
const helperSourcePath = packageName
|
|
16
|
+
? `${packageName.replaceAll('.', '/')}/${JAVA_STDIN_HELPER_CLASS}.java`
|
|
17
|
+
: `${JAVA_STDIN_HELPER_CLASS}.java`;
|
|
18
|
+
const transformedCode = code.replaceAll('System.in', `${JAVA_STDIN_HELPER_CLASS}.open()`);
|
|
19
|
+
const encodedBytes = [...new TextEncoder().encode(stdin)].join(', ');
|
|
20
|
+
return {
|
|
21
|
+
usesStdin: true,
|
|
22
|
+
stdinCacheKey: stdin,
|
|
23
|
+
transformedCode,
|
|
24
|
+
helperSourcePath,
|
|
25
|
+
helperSource: `${packageName ? `package ${packageName};\n\n` : ''}import java.io.InputStream;
|
|
26
|
+
import org.teavm.jso.JSObject;
|
|
27
|
+
import org.teavm.jso.browser.Window;
|
|
28
|
+
import org.teavm.jso.core.JSFunction;
|
|
29
|
+
import org.teavm.jso.core.JSMapLike;
|
|
30
|
+
|
|
31
|
+
final class ${JAVA_STDIN_HELPER_CLASS} extends InputStream {
|
|
32
|
+
private static final byte[] INITIAL_DATA = new byte[] { ${encodedBytes} };
|
|
33
|
+
private static final ${JAVA_STDIN_HELPER_CLASS} INSTANCE = new ${JAVA_STDIN_HELPER_CLASS}();
|
|
34
|
+
private int position = 0;
|
|
35
|
+
|
|
36
|
+
private ${JAVA_STDIN_HELPER_CLASS}() {
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static InputStream open() {
|
|
40
|
+
return INSTANCE;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private int readFromHost() {
|
|
44
|
+
Window current = Window.current();
|
|
45
|
+
if (current == null) {
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
JSMapLike<JSObject> globals = current.cast();
|
|
49
|
+
JSObject stdin = globals.get("wasmIdleJavaStdin");
|
|
50
|
+
if (stdin == null) {
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
JSFunction readByte = stdin.<JSMapLike<JSObject>>cast().get("readByte").cast();
|
|
54
|
+
Object value = readByte.call(stdin);
|
|
55
|
+
return value != null ? Integer.parseInt(value.toString()) : -1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Override
|
|
59
|
+
public int read(byte[] b, int off, int len) {
|
|
60
|
+
if (b == null) {
|
|
61
|
+
throw new NullPointerException();
|
|
62
|
+
}
|
|
63
|
+
if (off < 0 || len < 0 || len > b.length - off) {
|
|
64
|
+
throw new IndexOutOfBoundsException();
|
|
65
|
+
}
|
|
66
|
+
if (len == 0) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
if (position < INITIAL_DATA.length) {
|
|
70
|
+
int count = Math.min(len, INITIAL_DATA.length - position);
|
|
71
|
+
System.arraycopy(INITIAL_DATA, position, b, off, count);
|
|
72
|
+
position += count;
|
|
73
|
+
return count;
|
|
74
|
+
}
|
|
75
|
+
int next = readFromHost();
|
|
76
|
+
if (next == -1) {
|
|
77
|
+
return -1;
|
|
78
|
+
}
|
|
79
|
+
b[off] = (byte) next;
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Override
|
|
84
|
+
public int read() {
|
|
85
|
+
return position < INITIAL_DATA.length ? INITIAL_DATA[position++] & 0xff : readFromHost();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
`
|
|
89
|
+
};
|
|
90
|
+
};
|
|
@@ -4,6 +4,15 @@ export interface DebugVariable {
|
|
|
4
4
|
name: string;
|
|
5
5
|
value: string;
|
|
6
6
|
}
|
|
7
|
+
export type CompilerDiagnosticSeverity = 'error' | 'warning' | 'other';
|
|
8
|
+
export interface CompilerDiagnostic {
|
|
9
|
+
fileName?: string | null;
|
|
10
|
+
lineNumber: number;
|
|
11
|
+
columnNumber?: number;
|
|
12
|
+
endColumnNumber?: number;
|
|
13
|
+
severity: CompilerDiagnosticSeverity;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
7
16
|
export type DebugVariableKind = 'number' | 'bool' | 'array' | 'text';
|
|
8
17
|
export type DebugArrayElementKind = 'int' | 'float' | 'double' | 'bool' | 'char';
|
|
9
18
|
export interface DebugVariableMetadata {
|
|
@@ -36,4 +45,5 @@ export interface SandboxExecutionOptions {
|
|
|
36
45
|
debug?: boolean;
|
|
37
46
|
breakpoints?: number[];
|
|
38
47
|
pauseOnEntry?: boolean;
|
|
48
|
+
stdin?: string;
|
|
39
49
|
}
|
|
@@ -1,27 +1,37 @@
|
|
|
1
|
+
import type { DebugCommand, DebugSessionEvent, SandboxExecutionOptions } from './options';
|
|
1
2
|
import type { Sandbox } from './sandbox';
|
|
2
|
-
import type { SandboxExecutionOptions } from './options';
|
|
3
3
|
declare class Python implements Sandbox {
|
|
4
4
|
ts: number;
|
|
5
5
|
output: any;
|
|
6
|
+
ondebug?: (event: DebugSessionEvent) => void;
|
|
6
7
|
image?: (data: {
|
|
7
8
|
mime: string;
|
|
8
9
|
b64: string;
|
|
9
10
|
ts?: number;
|
|
10
11
|
}) => void;
|
|
11
|
-
worker
|
|
12
|
+
worker?: Worker;
|
|
12
13
|
buffer: SharedArrayBuffer;
|
|
14
|
+
debugBuffer: SharedArrayBuffer;
|
|
15
|
+
watchBuffer: SharedArrayBuffer;
|
|
16
|
+
watchResultBuffer: SharedArrayBuffer;
|
|
13
17
|
interruptBuffer: SharedArrayBuffer;
|
|
14
|
-
|
|
18
|
+
pendingInput: string[];
|
|
15
19
|
begin: number;
|
|
16
20
|
elapse: number;
|
|
17
21
|
uid: number;
|
|
22
|
+
waitingForInput: boolean;
|
|
23
|
+
pendingEof: boolean;
|
|
24
|
+
exit: boolean;
|
|
18
25
|
load(path: string, code?: string, log?: boolean, _args?: string[], _options?: SandboxExecutionOptions): Promise<void>;
|
|
19
26
|
write(input: string): void;
|
|
20
|
-
_write(input: string): void;
|
|
21
27
|
eof(): void;
|
|
28
|
+
private flushPendingInput;
|
|
22
29
|
run(code: string, prepare: boolean, _log?: boolean, _prog?: {
|
|
23
30
|
set?: (value: number) => void;
|
|
24
|
-
} | import('svelte/store').Writable<number>, _args?: string[],
|
|
31
|
+
} | import('svelte/store').Writable<number>, _args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
|
|
32
|
+
debugCommand(command: DebugCommand): void;
|
|
33
|
+
debugEvaluate(expression: string): Promise<string>;
|
|
34
|
+
kill(): void;
|
|
25
35
|
terminate(): void;
|
|
26
36
|
clear(): Promise<void>;
|
|
27
37
|
}
|