MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / compile

Method compile

app/src/DataModel/Scripting/ControlScriptWorker.cpp:478–527  ·  view source on GitHub ↗

* @brief Builds the engine, evals the SDK, and grabs setup()/loop(). Only __ss_bridge goes * in: the direct helper bridges wrap main-thread singletons and must never execute on * this worker thread (__ss_control tells the prelude to marshal instead). User source * is evaluated under the armed watchdog so a top-level loop cannot wedge the worker. */

Source from the content-addressed store, hash-verified

476 * is evaluated under the armed watchdog so a top-level loop cannot wedge the worker.
477 */
478bool DataModel::ControlScriptWorker::compile(const QString& source, QString& errorOut)
479{
480 m_engine = std::make_unique<QJSEngine>();
481 m_engine->installExtensions(QJSEngine::ConsoleExtension | QJSEngine::GarbageCollectionExtension);
482 m_watchdog = std::make_unique<DataModel::JsWatchdog>(
483 m_engine.get(), kRuntimeWatchdogMs, QStringLiteral("Control script"));
484
485 m_bridge = new ControlApiBridge(m_marshaller, m_engine.get());
486 m_bridge->setWatchdog(m_watchdog.get());
487 auto bridgeVal = m_engine->newQObject(m_bridge);
488 m_engine->globalObject().setProperty(QStringLiteral("__ss_bridge"), bridgeVal);
489 m_engine->globalObject().setProperty(QStringLiteral("__ss_control"), QJSValue(true));
490
491 QFile sdkFile(QStringLiteral(":/api/SerialStudio.js"));
492 if (sdkFile.open(QFile::ReadOnly))
493 m_engine->evaluate(QString::fromUtf8(sdkFile.readAll()));
494
495 m_watchdog->arm();
496 const auto result = m_engine->evaluate(source, QStringLiteral("control-script.js"));
497 m_watchdog->disarm();
498
499 if (m_engine->isInterrupted()) {
500 m_engine->setInterrupted(false);
501 errorOut = QStringLiteral("Script did not finish evaluating within %1 ms and was "
502 "interrupted (infinite loop at the top level?).")
503 .arg(kRuntimeWatchdogMs);
504 releaseEngine();
505 return false;
506 }
507
508 if (result.isError()) {
509 errorOut = QStringLiteral("Line %1: %2")
510 .arg(result.property(QStringLiteral("lineNumber")).toInt())
511 .arg(result.toString());
512 releaseEngine();
513 return false;
514 }
515
516 m_setupFn = m_engine->globalObject().property(QStringLiteral("setup"));
517 m_loopFn = m_engine->globalObject().property(QStringLiteral("loop"));
518
519 if (!m_setupFn.isCallable() && !m_loopFn.isCallable()) {
520 errorOut = QStringLiteral("Script must define setup() and/or loop().");
521 releaseEngine();
522 return false;
523 }
524
525 m_loaded = true;
526 return true;
527}

Callers

nothing calls this directly

Calls 7

setWatchdogMethod · 0.80
disarmMethod · 0.80
isErrorMethod · 0.80
getMethod · 0.45
openMethod · 0.45
evaluateMethod · 0.45
armMethod · 0.45

Tested by

no test coverage detected