-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjavascript_runner.cpp
More file actions
102 lines (86 loc) · 2.99 KB
/
Copy pathjavascript_runner.cpp
File metadata and controls
102 lines (86 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "javascript_runner.h"
#include <QMutexLocker>
#include <QProcess>
#include <QTemporaryDir>
#include <QTemporaryFile>
#include <QFileInfo>
#include <QDir>
#include <QElapsedTimer>
#include <QDebug>
#include <QCoreApplication>
JavascriptRunner::JavascriptRunner()
{
m_initialised = true;
}
JavascriptRunner::~JavascriptRunner()
{
}
EmbeddedRunner::Result JavascriptRunner::execute(const QString &code,
const QString &stdinInput,
volatile bool *abort,
const QMap<QString, QString> &additionalFiles)
{
QMutexLocker lock(&m_mutex);
Result result;
QTemporaryDir tmpDir;
if (!tmpDir.isValid()) {
result.error = QStringLiteral("Failed to create temp directory");
result.exitCode = -1;
return result;
}
const QString srcPath = tmpDir.filePath(QStringLiteral("user_code.js"));
QFile srcFile(srcPath);
if (!srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
result.error = QStringLiteral("Failed to write source file");
result.exitCode = -1;
return result;
}
srcFile.write(code.toUtf8());
srcFile.close();
for (auto it = additionalFiles.begin(); it != additionalFiles.end(); ++it) {
QFile file(tmpDir.filePath(it.key()));
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
file.write(it.value().toUtf8());
file.close();
}
}
QProcess runProc;
runProc.setWorkingDirectory(tmpDir.path());
QString basePath = QCoreApplication::applicationDirPath();
#ifdef Q_OS_WIN
QString wasmerExe = QDir::cleanPath(basePath + "/../tools/wasmer/bin/wasmer.exe");
#else
QString wasmerExe = QDir::cleanPath(basePath + "/../tools/wasmer/bin/wasmer");
#endif
QStringList args;
args << "run" << "--volume" << ".:/" << "syrusakbary/quickjs" << "--command" << "qjs" << "--" << "user_code.js";
runProc.start(wasmerExe, args);
if (!stdinInput.isEmpty()) {
runProc.write(stdinInput.toUtf8());
}
runProc.closeWriteChannel();
const int TIMEOUT_MS = 60000;
QElapsedTimer timer;
timer.start();
while (!runProc.waitForFinished(100)) {
QCoreApplication::processEvents();
if (abort && *abort) {
runProc.kill();
result.error = QStringLiteral("Execution stopped by user");
result.exitCode = -1;
result.timedOut = false;
return result;
}
if (timer.elapsed() >= TIMEOUT_MS) {
runProc.kill();
result.error = QStringLiteral("Time limit exceeded (60 s)");
result.exitCode = -1;
result.timedOut = true;
return result;
}
}
result.output = QString::fromLocal8Bit(runProc.readAllStandardOutput());
result.error = QString::fromLocal8Bit(runProc.readAllStandardError());
result.exitCode = runProc.exitCode();
return result;
}