diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e6facb5..eb7f02a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,15 +46,17 @@ if (BUILD_EMULATOR) src/Primitives/emulated.cpp src/Interpreter/instructions.cpp src/Interpreter/interpreter.cpp + src/Interpreter/proxied.cpp src/Memory/mem.cpp src/Utils/util.cpp src/Utils/util_arduino.cpp src/Utils/macros.cpp src/Utils/sockets.cpp src/Debug/debugger.cpp - src/Edward/proxy.cpp - src/Edward/proxy_supervisor.cpp - src/Edward/RFC.cpp + src/Oop/proxy.cpp + src/Oop/proxy_supervisor.cpp + src/Oop/RFC.cpp + src/Oop/stateful.cpp ) add_definitions(-DINFO=0) @@ -87,15 +89,17 @@ if (BUILD_UNITTEST) src/Primitives/emulated.cpp src/Interpreter/instructions.cpp src/Interpreter/interpreter.cpp + src/Interpreter/proxied.cpp src/Memory/mem.cpp src/Utils/util.cpp src/Utils/util_arduino.cpp src/Utils/macros.cpp src/Utils/sockets.cpp src/Debug/debugger.cpp - src/Edward/proxy.cpp - src/Edward/proxy_supervisor.cpp - src/Edward/RFC.cpp + src/Oop/proxy.cpp + src/Oop/proxy_supervisor.cpp + src/Oop/RFC.cpp + src/Oop/stateful.cpp ) # Set default compile flags for GCC diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 12abbd25e..73a54e360 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -2,11 +2,12 @@ set(SOURCE_FILES ../../src/Debug/debugger.cpp ../../src/Interpreter/instructions.cpp ../../src/Interpreter/interpreter.cpp + ../../src/Interpreter/proxied.cpp ../../src/Memory/mem.cpp ../../src/Primitives/idf.cpp - ../../src/Edward/proxy.cpp - ../../src/Edward/proxy_supervisor.cpp - ../../src/Edward/RFC.cpp + ../../src/Oop/proxy.cpp + ../../src/Oop/proxy_supervisor.cpp + ../../src/Oop/RFC.cpp ../../src/Utils/macros.cpp ../../src/Utils/sockets.cpp ../../src/Utils/util.cpp diff --git a/platforms/Zephyr/CMakeLists.txt b/platforms/Zephyr/CMakeLists.txt index 0ed056c05..0bd989a1c 100644 --- a/platforms/Zephyr/CMakeLists.txt +++ b/platforms/Zephyr/CMakeLists.txt @@ -25,9 +25,9 @@ target_sources(app PRIVATE ../../src/Utils/macros.cpp ../../src/Utils/sockets.cpp ../../src/Debug/debugger.cpp - ../../src/Edward/proxy.cpp - ../../src/Edward/proxy_supervisor.cpp - ../../src/Edward/RFC.cpp + ../../src/Oop/proxy.cpp + ../../src/Oop/proxy_supervisor.cpp + ../../src/Oop/RFC.cpp upload.h ) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index fbd77bd12..79f5bd651 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -10,6 +10,7 @@ #include "../../lib/json/single_include/nlohmann/json.hpp" #endif +#include "../Interpreter/proxied.h" #include "../Memory/mem.h" #include "../Primitives/primitives.h" #include "../Utils//util.h" @@ -179,6 +180,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { debug("received interrupt %x\n", *interruptData); fflush(stdout); + printf("Interrupt: %x\n", *interruptData); this->channel->write("Interrupt: %x\n", *interruptData); long start = 0, size = 0; @@ -311,6 +313,11 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->channel->write("%s!\n", receivingData ? "ack" : "done"); } break; + case interruptTransfer: + this->transfer(m, interruptData); + free(interruptData); + this->channel->write("Transferred!\n"); + break; case interruptProxyCall: { this->handleProxyCall(m, program_state, interruptData + 1); free(interruptData); @@ -362,6 +369,10 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->removeOverride(m, interruptData + 1); free(interruptData); break; + case interruptStore: + this->receiveStore(m, interruptData + 1); + free(interruptData); + break; default: // handle later this->channel->write("COULD not parse interrupt data!\n"); @@ -449,12 +460,12 @@ void Debugger::handleInterruptRUN(const Module *m, *program_state = WARDUINOrun; } -void Debugger::handleSTEP(const Module *m, RunningState *program_state) { +void Debugger::handleSTEP(Module *m, RunningState *program_state) { *program_state = WARDUINOstep; this->skipBreakpoint = m->pc_ptr; } -void Debugger::handleSTEPOver(const Module *m, RunningState *program_state) { +void Debugger::handleSTEPOver(Module *m, RunningState *program_state) { this->skipBreakpoint = m->pc_ptr; uint8_t const opcode = *m->pc_ptr; if (opcode == 0x10) { // step over direct call @@ -1115,6 +1126,31 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { debug("done with first msg\n"); } +void Debugger::load(uint8_t *bytes, Module *m) { + auto start = read_B8(&bytes); + auto limit = read_B8(&bytes); + auto total_bytes = limit - start + 1; + this->channel->write("loading into %u - %u \n", start, limit); + memcpy(m->memory.bytes + start, bytes, total_bytes); +} + +void Debugger::transfer(Module *m, uint8_t *interruptData) { + uint8_t *cursor = interruptData; + uint8_t *end = nullptr; + uint16_t len = read_B16(&(++cursor)); + end = cursor + len; + + while (cursor < end) { + switch (*cursor++) { + case memoryState: + load(cursor, m); + default: { + debug("do nothing\n"); + } + } + } +} + bool Debugger::saveState(Module *m, uint8_t *interruptData) { uint8_t *program_state = nullptr; uint8_t *end_state = nullptr; @@ -1413,7 +1449,12 @@ uintptr_t Debugger::readPointer(uint8_t **data) { void Debugger::proxify() { WARDuino::instance()->program_state = PROXYhalt; + delete WARDuino::instance()->interpreter; + WARDuino::instance()->interpreter = new Proxied(); this->proxy = new Proxy(); // TODO delete + if (this->channel) { + this->channel->write("PROXIED!\n"); + } } void Debugger::handleProxyCall(Module *m, RunningState *, @@ -1431,7 +1472,7 @@ void Debugger::handleProxyCall(Module *m, RunningState *, StackValue *args = Proxy::readRFCArgs(func, data); dbg_trace("Enqueuing callee %" PRIu32 "\n", func->fidx); - auto *rfc = new RFC(fidx, func->type, args); + auto *rfc = new RFC(m, fidx, func->type, args); this->proxy->pushRFC(m, rfc); } @@ -1451,8 +1492,8 @@ void Debugger::sendProxyCallResult(Module *m) const { bool Debugger::isProxy() const { return this->proxy != nullptr; } -bool Debugger::isProxied(const uint32_t fidx) const { - return this->supervisor != nullptr && this->supervisor->isProxied(fidx); +bool Debugger::isProxied(Module *m, const uint32_t fidx) const { + return this->supervisor != nullptr && fidx < m->import_count; } void Debugger::handleMonitorProxies(const Module *m, @@ -1500,6 +1541,15 @@ void Debugger::updateCallbackmapping(Module *m, const char *interruptData) { } } +void Debugger::receiveStore(Module *m, uint8_t *interruptData) { + uint8_t *pos = interruptData; + uint32_t addr = read_LEB_32(&pos); + auto *sval = (StackValue *)malloc(sizeof(struct StackValue)); + deserialiseStackValue(pos, true, sval); + m->warduino->interpreter->store(m, sval->value_type, addr, *sval); + free(sval); +} + // Stop the debugger void Debugger::stop() { if (this->channel != nullptr) { @@ -1645,6 +1695,7 @@ void Debugger::notifyCompleteStep(Module *m) const { m->warduino->debugger->checkpoint(m); } this->channel->write("STEP!\n"); + printf("STEP!\n"); } Debugger::~Debugger() { diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 98f28e484..3cc79ab31 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -11,8 +11,7 @@ #include #include -#include "../Edward/proxy.h" -#include "../Edward/proxy_supervisor.h" +#include "../Oop/proxy.h" #include "../Threading/warduino-thread.h" #include "../Utils/sockets.h" @@ -77,6 +76,9 @@ enum InterruptTypes { // Remote REPL interruptINVOKE = 0x40, + // Stateful out-of-place + interruptTransfer = 0x52, + // Pull Debugging interruptSnapshot = 0x60, interruptSetSnapshotPolicy = 0x61, @@ -99,7 +101,6 @@ enum InterruptTypes { // Operations interruptStore = 0xa0, - interruptStored = 0xa1, }; enum class SnapshotPolicy : int { @@ -109,6 +110,8 @@ enum class SnapshotPolicy : int { // points where primitives are used. }; +class ProxySupervisor; + class Debugger { private: std::deque debugMessages = {}; @@ -159,9 +162,9 @@ class Debugger { void handleInterruptRUN(const Module *m, RunningState *program_state); - void handleSTEP(const Module *m, RunningState *program_state); + void handleSTEP(Module *m, RunningState *program_state); - void handleSTEPOver(const Module *m, RunningState *program_state); + void handleSTEPOver(Module *m, RunningState *program_state); void handleInterruptBP(Module *m, uint8_t *interruptData); @@ -208,11 +211,15 @@ class Debugger { bool saveState(Module *m, uint8_t *interruptData); + void load(uint8_t *bytes, Module *m); + + void transfer(Module *m, uint8_t *interruptData); + static uintptr_t readPointer(uint8_t **data); static void updateCallbackmapping(Module *m, const char *interruptData); - bool operation(Module *m, operation op); + void receiveStore(Module *m, uint8_t *interruptData); public: // Public fields @@ -283,7 +290,7 @@ class Debugger { bool isProxy() const; - bool isProxied(uint32_t fidx) const; + bool isProxied(Module *m, uint32_t fidx) const; void startProxySupervisor(Channel *socket); diff --git a/src/Edward/RFC.cpp b/src/Edward/RFC.cpp deleted file mode 100644 index 8bcf131e3..000000000 --- a/src/Edward/RFC.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "RFC.h" - -RFC::RFC(uint32_t id, Type *t_type, StackValue *t_args) - : fidx(id), args(t_args), type(t_type) {} diff --git a/src/Edward/RFC.h b/src/Edward/RFC.h deleted file mode 100644 index 2ed7b9c84..000000000 --- a/src/Edward/RFC.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -struct StackValue; -struct Type; - -struct SerializeData { - const unsigned char *raw; - uint32_t size; -}; - -class RFC { - public: - const uint32_t fidx; - StackValue *args; - const Type *type; - StackValue *result; - - bool success = true; - char *exception; - uint16_t exception_size; - - RFC(uint32_t id, Type *t_type, StackValue *t_args = nullptr); -}; diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 0e4ceb3cc..543c8c5c4 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -17,9 +17,9 @@ bool proxy_call(Module *m, uint32_t fidx) { if (type->param_count > 0) { m->sp -= type->param_count; StackValue *args = &m->stack[m->sp + 1]; - rfc = new RFC(fidx, type, args); + rfc = new RFC(m, fidx, type, args); } else { - rfc = new RFC(fidx, type); + rfc = new RFC(m, fidx, type); } if (!supervisor->call(rfc)) { @@ -282,7 +282,7 @@ bool i_instr_return(Module *m) { bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); - if (m->warduino->debugger->isProxied(fidx)) { + if (m->warduino->debugger->isProxied(m, fidx)) { return proxy_call(m, fidx); } diff --git a/src/Interpreter/interpreter.cpp b/src/Interpreter/interpreter.cpp index 5e6d6b18d..be7eb1b28 100644 --- a/src/Interpreter/interpreter.cpp +++ b/src/Interpreter/interpreter.cpp @@ -113,10 +113,6 @@ uint32_t STORE_SIZE[] = {4, 8, 4, 8, 1, 2, 1, 2, 4}; bool Interpreter::store(Module *m, uint8_t type, uint32_t addr, StackValue &sval) { - if (m->warduino->debugger->isProxy()) { - return m->warduino->debugger; - } - uint8_t *maddr, *mem_end; uint32_t size = STORE_SIZE[abs(type - I32)]; bool overflow = false; @@ -474,3 +470,5 @@ void Interpreter::report_overflow([[maybe_unused]] Module *m, m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE, maddr); sprintf(exception, "out of bounds memory access"); } + +Interpreter::~Interpreter() {} diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index d11260d34..9d5acc576 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -6,6 +6,8 @@ class Interpreter { public: + virtual ~Interpreter(); + /** * Push a new frame on to the call stack * @param m module @@ -48,7 +50,8 @@ class Interpreter { /* Stateful operations * ************************************************************************/ - bool store(Module *m, uint8_t type, uint32_t addr, StackValue &sval); + virtual bool store(Module *m, uint8_t type, uint32_t addr, + StackValue &sval); bool load(Module *m, uint8_t type, uint32_t addr, uint32_t offset); diff --git a/src/Interpreter/proxied.cpp b/src/Interpreter/proxied.cpp new file mode 100644 index 000000000..189bc889f --- /dev/null +++ b/src/Interpreter/proxied.cpp @@ -0,0 +1,23 @@ +#include "./proxied.h" + +#include "../Debug/debugger.h" +#include "../Utils//util.h" + +void send_leb(Channel *channel, uint32_t value, const char *end = "") { + uint8_t *buffer = write_LEB(value); + uint32_t size = size_leb(value); + for (uint32_t i = 0; i < size; ++i) { + channel->write("%02" PRIx8 "%s", buffer[i], end); + } + free(buffer); +} + +bool Proxied::store(Module *m, [[maybe_unused]] uint8_t type, uint32_t addr, + StackValue &sval) { + Interpreter::store(m, type, addr, sval); + // m->warduino->debugger->channel->write("%02" PRIx8, interruptStore); + // send_leb(m->warduino->debugger->channel, addr); + // send_leb(m->warduino->debugger->channel, 0); + // send_leb(m->warduino->debugger->channel, sval.value.uint32, "\n"); + return true; +} diff --git a/src/Interpreter/proxied.h b/src/Interpreter/proxied.h new file mode 100644 index 000000000..dccdb5bc0 --- /dev/null +++ b/src/Interpreter/proxied.h @@ -0,0 +1,6 @@ +#include "./interpreter.h" +class Proxied : public Interpreter { + public: + bool store(Module *m, uint8_t type, uint32_t addr, + StackValue &sval) override; +}; \ No newline at end of file diff --git a/src/Oop/RFC.cpp b/src/Oop/RFC.cpp new file mode 100644 index 000000000..ac93e9c12 --- /dev/null +++ b/src/Oop/RFC.cpp @@ -0,0 +1,58 @@ +#include "RFC.h" + +#include +#include + +RFC::RFC(Module *m, uint32_t id, Type *t_type, StackValue *t_args) + : m(m), fidx(id), args(t_args), type(t_type) {} + +SerializeData *merge(SerializeData a, SerializeData b, bool divide) { + auto *data = new SerializeData; + auto padding = divide ? 2 : 1; + data->size = a.size + b.size + padding; + // size_t lengte = a.size + b.size + padding; + data->raw = new char[data->size]; //(unsigned char *)calloc(data->size, + //sizeof(char)); + if (divide) { + *(data->raw + a.size) = '\n'; + *(data->raw + a.size + b.size + 1) = '\n'; + padding = 1; + } else { + padding = 0; + } + std::memcpy(data->raw, a.raw, a.size); + std::memcpy(data->raw + a.size + padding, b.raw, b.size); + return data; +} + +struct SerializeData *mergeSerializeData(struct SerializeData data1, + struct SerializeData data2, + bool divide) { + // Allocate memory for the result struct + struct SerializeData *result = + static_cast(malloc(sizeof(struct SerializeData))); + if (result == NULL) { + return NULL; // Memory allocation failure + } + + uint32_t extra = divide ? 1 : 0; + result->size = data1.size + data2.size + extra; + result->raw = static_cast(malloc(result->size)); + if (result->raw == NULL) { + free(result); + return NULL; // Memory allocation failure + } + + // Copy the first data block + memcpy(result->raw, data1.raw, data1.size); + + // Optionally add a newline character + if (divide) { + result->raw[data1.size] = '\n'; + } + + // Copy the second data block after the newline (if inserted) + memcpy(result->raw + data1.size + extra, data2.raw, data2.size); + + return result; +} \ No newline at end of file diff --git a/src/Oop/RFC.h b/src/Oop/RFC.h new file mode 100644 index 000000000..39d40013c --- /dev/null +++ b/src/Oop/RFC.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "../WARDuino/internals.h" +struct StackValue; +struct Type; + +struct SerializeData { + char *raw; + uint32_t size; +}; + +SerializeData *merge(SerializeData a, SerializeData b, bool divide = true); + +struct SerializeData *mergeSerializeData(struct SerializeData data1, + struct SerializeData data2, + bool divide = true); + +class RFC { + public: + Module *m; + const uint32_t fidx; + StackValue *args; + const Type *type; + StackValue *result; + + bool success = true; + char *exception; + uint16_t exception_size; + + RFC(Module *m, uint32_t id, Type *t_type, StackValue *t_args = nullptr); +}; diff --git a/src/Edward/proxy.cpp b/src/Oop/proxy.cpp similarity index 85% rename from src/Edward/proxy.cpp rename to src/Oop/proxy.cpp index df3b40053..814345699 100644 --- a/src/Edward/proxy.cpp +++ b/src/Oop/proxy.cpp @@ -7,6 +7,7 @@ #include #include "../Interpreter/instructions.h" +#include "../Primitives/primitives.h" #include "../Utils/macros.h" #include "../Utils/util.h" @@ -30,8 +31,12 @@ void Proxy::pushRFC(Module *m, RFC *rfc) { this->setupCalleeArgs(m, rfc); if (rfc->fidx < m->import_count) { - // execute primitives directly - ((Primitive)m->functions[rfc->fidx].func_ptr)(m); + // try with forward state transfer + if (!do_forward(m, rfc->fidx)) { + // on fail: execute primitives directly + ((Primitive)m->functions[rfc->fidx].func_ptr)(m); + } + // send result directly m->warduino->program_state = PROXYhalt; m->warduino->debugger->sendProxyCallResult(m); @@ -51,25 +56,27 @@ RFC *Proxy::topRFC() { return this->calls->top(); } void Proxy::returnResult(Module *m) { RFC *rfc = this->calls->top(); + // return result + // remove call from lifo queue this->calls->pop(); if (!rfc->success) { // TODO exception msg - WARDuino::instance()->debugger->channel->write(R"({"success":false})"); + WARDuino::instance()->debugger->channel->write("{\"success\":false}\n"); return; } if (rfc->type->result_count == 0) { // reading result from stack - WARDuino::instance()->debugger->channel->write(R"({"success":true})"); + WARDuino::instance()->debugger->channel->write("{\"success\":true}\n"); return; } // send the result to the client rfc->result = &m->stack[m->sp]; char *val = printValue(rfc->result); - WARDuino::instance()->debugger->channel->write(R"({"success":true,%s})", + WARDuino::instance()->debugger->channel->write("{\"success\":true,%s}\n", val); free(val); } diff --git a/src/Edward/proxy.h b/src/Oop/proxy.h similarity index 100% rename from src/Edward/proxy.h rename to src/Oop/proxy.h diff --git a/src/Edward/proxy_supervisor.cpp b/src/Oop/proxy_supervisor.cpp similarity index 82% rename from src/Edward/proxy_supervisor.cpp rename to src/Oop/proxy_supervisor.cpp index 511efca99..e11b05e9a 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Oop/proxy_supervisor.cpp @@ -12,6 +12,7 @@ #include "../../lib/json/single_include/nlohmann/json.hpp" #endif +#include "../Primitives/primitives.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../WARDuino/CallbackHandler.h" @@ -53,9 +54,9 @@ Event *parseJSON(char *buff) { return new Event(*parsed.find("topic"), payload); } -ProxySupervisor::ProxySupervisor(Channel *duplex, warduino::mutex *mutex) { +ProxySupervisor::ProxySupervisor(Channel *duplex, warduino::mutex *mutex) + : Debugger(duplex) { debug("Starting supervisor.\n"); - this->channel = duplex; this->mutex = mutex; this->thread = warduino::thread(runSupervisor, this); this->proxyResult = nullptr; @@ -70,40 +71,22 @@ bool isReply(nlohmann::basic_json<> parsed) { } void ProxySupervisor::listenToSocket() { - char _char; - uint32_t buf_idx = 0; - const uint32_t start_size = 1024; - uint32_t current_size = start_size; - char *buffer = (char *)malloc(start_size); + uint8_t message[1024] = {0}; ssize_t readAmount; this->channel->open(); dbg_info("Proxy supervisor listening to remote device...\n"); while (continuing(this->mutex)) { - readAmount = this->channel->read(&_char, 1); + readAmount = this->channel->read(message, 1024); if (readAmount == -1) { printf("Proxy supervisor shutting down.\n"); exit(-1); } if (readAmount > 0) { - // increase buffer size if needed - if (current_size <= (buf_idx + 1)) { - char *new_buff = (char *)malloc(current_size + start_size); - memcpy((void *)new_buff, (void *)buffer, current_size); - free(buffer); - buffer = new_buff; - current_size += start_size; - printf("increasing PushClient's buffer size to %" PRId32 "\n", - current_size); - } - buffer[buf_idx++] = _char; - // manual null-termination is needed because parseJSON does not use - // first len argument - buffer[buf_idx] = '\0'; try { - nlohmann::basic_json<> parsed = nlohmann::json::parse(buffer); - debug("parseJSON: %s\n", parsed.dump().c_str()); + nlohmann::basic_json<> parsed = nlohmann::json::parse(message); + printf("parseJSON: %s\n", parsed.dump().c_str()); if (isEvent(parsed)) { CallbackHandler::push_event(new Event( @@ -115,13 +98,10 @@ void ProxySupervisor::listenToSocket() { this->hasReplied = true; this->proxyResult = parsed; } - - buf_idx = 0; } catch (const nlohmann::detail::parse_error &e) { - if (_char == '\n') { - // discard buffer - buf_idx = 0; - } + printf("Non RFC call: %s", message); + printf("error: %s", e.what()); + WARDuino::instance()->handleInterrupt(readAmount, message); } } } @@ -133,9 +113,13 @@ bool ProxySupervisor::send( return n == size; } -nlohmann::basic_json<> ProxySupervisor::readReply() { - while (!this->hasReplied); +nlohmann::basic_json<> ProxySupervisor::readReply(RFC *rfc) { + while (!this->hasReplied) { + WARDuino::instance()->debugger->checkDebugMessages( + rfc->m, &WARDuino::instance()->program_state); + } WARDuino::instance()->debugger->channel->write("read reply: succeeded\n"); + printf("read reply: succeeded\n"); this->hasReplied = false; return this->proxyResult; } @@ -204,21 +188,24 @@ struct SerializeData *ProxySupervisor::serializeRFC(RFC *callee) { // array as hexa const uint32_t hexa_size = serializationSize * 2; - auto *hexa = - new unsigned char[hexa_size + 2]; //+2 for '\n' and '0' termination + auto *hexa = new char[hexa_size + 2]; //+2 for '\n' and '0' termination chars_as_hexa(hexa, buffer, serializationSize); hexa[hexa_size] = '\n'; hexa[hexa_size + 1] = '\0'; // TODO remove zero termination and +2 above delete[] buffer; - auto *ser = new SerializeData; - ser->size = hexa_size + 1; - ser->raw = hexa; - return ser; + auto *message = new SerializeData; + message->size = hexa_size + 1; + message->raw = hexa; + + auto transfer = get_backward(callee->m, callee->fidx); + this->channel->write(transfer.c_str()); + + return message; } void ProxySupervisor::deserializeRFCResult(RFC *rfc) { - nlohmann::basic_json<> call_result = this->readReply(); // blocking + nlohmann::basic_json<> call_result = this->readReply(rfc); // blocking rfc->success = *call_result.find("success"); if (rfc->type->result_count == 0) { @@ -260,6 +247,7 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { } bool ProxySupervisor::call(RFC *callee) { + printf("serializing RFC\n"); struct SerializeData *rfc_request = this->serializeRFC(callee); bool sent = this->send((void *)rfc_request->raw, rfc_request->size); @@ -273,11 +261,12 @@ bool ProxySupervisor::call(RFC *callee) { } // Fetch new callback mapping // convert message to hex TODO: move to proxyserver - char cmdBuffer[10] = ""; - int cmdBufferLen = 0; - sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); - WARDuino::instance()->debugger->supervisor->send(cmdBuffer, cmdBufferLen); + // char cmdBuffer[10] = ""; + // int cmdBufferLen = 0; + // sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, + // &cmdBufferLen); this->send(cmdBuffer, cmdBufferLen); this->deserializeRFCResult(callee); + printf("end of supervisor::call(rfc)\n"); return true; } diff --git a/src/Edward/proxy_supervisor.h b/src/Oop/proxy_supervisor.h similarity index 88% rename from src/Edward/proxy_supervisor.h rename to src/Oop/proxy_supervisor.h index 40b0bb55c..dd7ba5022 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Oop/proxy_supervisor.h @@ -6,6 +6,7 @@ #include #include +#include "../Debug/debugger.h" #include "../Threading/warduino-thread.h" #include "../Utils/sockets.h" #include "RFC.h" @@ -16,9 +17,8 @@ #endif #include "sys/types.h" -class ProxySupervisor { +class ProxySupervisor : public Debugger { private: - Channel *channel; warduino::mutex *mutex; std::set *proxied = new std::set(); @@ -36,7 +36,7 @@ class ProxySupervisor { void listenToSocket(); bool send(void *t_buffer, int t_size); - nlohmann::basic_json<> readReply(); + nlohmann::basic_json<> readReply(RFC *rfc); bool call(RFC *callee); diff --git a/src/Oop/stateful.cpp b/src/Oop/stateful.cpp new file mode 100644 index 000000000..e8e9814f6 --- /dev/null +++ b/src/Oop/stateful.cpp @@ -0,0 +1,15 @@ +#include "stateful.h" + +#include "../Utils/util.h" + +char *sync_memory(Module *m, uint32_t start, uint32_t end) { + uint8_t len = end - start; + auto *buffer = (char *)calloc(sizeof(char), (2 * len) + 8); + + sprintf(buffer, "%02" PRIx8 "%02" PRIx8 "%02" PRIx8, memoryState, start, + end); + auto target = m->memory.bytes + start; + slebf(buffer + 6, target, len, "\n"); + + return buffer; +} \ No newline at end of file diff --git a/src/Oop/stateful.h b/src/Oop/stateful.h new file mode 100644 index 000000000..5642d1963 --- /dev/null +++ b/src/Oop/stateful.h @@ -0,0 +1,5 @@ +#pragma once + +#include "../WARDuino.h" + +char *sync_memory(Module *m, uint32_t start, uint32_t end); diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 28548ae0a..911a7ea90 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -21,13 +21,14 @@ #include #include "../Memory/mem.h" +#include "../Oop/stateful.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../WARDuino/CallbackHandler.h" #include "primitives.h" -#define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 29 +#define NUM_PRIMITIVES 30 +#define NUM_PRIMITIVES_ARDUINO 0 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -46,9 +47,13 @@ double sensor_emu = 0; if (prim_index < ALL_PRIMITIVES) { \ PrimitiveEntry *p = &primitives[prim_index++]; \ p->name = #prim_name; \ + p->t = &(prim_name##_type); \ + p->index = prim_index - 1; \ p->f = &(prim_name); \ p->f_reverse = nullptr; \ p->f_serialize_state = nullptr; \ + p->f_backward = nullptr; \ + p->f_forward = nullptr; \ } else { \ FATAL("prim_index out of bounds"); \ } \ @@ -61,6 +66,18 @@ double sensor_emu = 0; p->f_serialize_state = &(prim_name##_serialize); \ } +#define install_primitive_backward(prim_name) \ + { \ + PrimitiveEntry *p = &primitives[prim_index - 1]; \ + p->f_backward = &(prim_name##_backward); \ + } + +#define install_primitive_forward(prim_name) \ + { \ + PrimitiveEntry *p = &primitives[prim_index - 1]; \ + p->f_forward = &(prim_name##_forward); \ + } + #define def_prim(function_name, type) \ Type function_name##_type = type; \ bool function_name([[maybe_unused]] Module *m) @@ -73,6 +90,12 @@ double sensor_emu = 0; void function_name##_serialize( \ std::vector &external_state) +#define def_prim_backward(function_name) \ + char *function_name##_backward([[maybe_unused]] Module *m) + +#define def_prim_forward(function_name) \ + char *function_name##_forward([[maybe_unused]] Module *m) + // TODO: use fp #define pop_args(n) m->sp -= n #define get_arg(m, arg) m->stack[(m)->sp - (arg)].value @@ -244,8 +267,38 @@ def_prim(abort, NoneToNoneU32) { return false; } +def_prim(dummy, twoToOneU32) { + printf("dummy \n"); + uint32_t a = arg1.uint32; + uint32_t b = arg0.uint32; + StackValue val = {I32, {42}}; + for (int i = 0; a + i < b; i += 4) { + m->warduino->interpreter->store(m, I32, a + i, val); + } + pop_args(2); + pushUInt32(b - a); + return true; +} + +def_prim_forward(dummy) { + printf("dummy \n"); + uint32_t a = arg1.uint32; + uint32_t b = arg0.uint32; + StackValue val = {I32, {42}}; + for (int i = 0; a + i < b; i += 4) { + m->warduino->interpreter->store(m, I32, a + i, val); + } + + printf("transfering state changes\n"); + auto transfer = sync_memory(m, a, b); + + pop_args(2); + pushUInt32(b - a); + return transfer; +} + def_prim(millis, NoneToOneU64) { - struct timeval tv {}; + struct timeval tv{}; gettimeofday(&tv, nullptr); unsigned long millis = 1000 * tv.tv_sec + tv.tv_usec; pushUInt64(millis); @@ -253,7 +306,7 @@ def_prim(millis, NoneToOneU64) { } def_prim(micros, NoneToOneU64) { - struct timeval tv {}; + struct timeval tv{}; gettimeofday(&tv, nullptr); unsigned long micros = 1000000 * tv.tv_sec + tv.tv_usec; pushUInt64(micros); @@ -514,6 +567,9 @@ def_prim(chip_ledc_attach_pin, twoToNoneU32) { void install_primitives() { dbg_info("INSTALLING PRIMITIVES\n"); dbg_info("INSTALLING FAKE ARDUINO\n"); + install_primitive(dummy); + install_primitive_forward(dummy); + install_primitive(abort); install_primitive(millis); install_primitive(micros); @@ -632,4 +688,47 @@ std::vector get_io_state(Module *) { return ioState; } +std::string get_backward(Module *m, uint32_t index) { + std::stringstream transfer; + auto *buffer = new char[6]; + sprintf(buffer, "%02" PRIx8 "00%02" PRIx8, interruptTransfer, 1); + delete[] buffer; + + if (index < ALL_PRIMITIVES) { + auto &primitive = primitives[index]; + printf("transfering for %s", primitive.name); + if (primitive.f_backward) { + m->sp += primitive.t->param_count; + auto data = primitive.f_backward(m); + transfer << std::string(buffer); + transfer << std::string(data); + free(data); + m->sp -= primitive.t->param_count; + } + } + return transfer.str(); +} + +// todo eliminate duplicate code +// fix length at start of 52 message +// send nothing if length is 0 + +bool do_forward(Module *m, uint32_t index) { + if (index < ALL_PRIMITIVES) { + auto &primitive = primitives[index]; + printf("transfering for %s", primitive.name); + if (primitive.f_forward) { + auto data = primitive.f_forward(m); + printf("transfer built\n"); + WARDuino::instance()->debugger->channel->write( + "%02" PRIx8 "00%02" PRIx8 "%s", interruptTransfer, 1, data); + free(data); + } + } else { + return false; + } + + return true; +} + #endif // ARDUINO diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 0a9509e90..2cf47179e 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -81,4 +81,8 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { primitive(m); } +bool do_forward(Module *m, uint32_t index); + +std::string get_backward(Module *m, uint32_t index); + #endif diff --git a/src/Utils/macros.h b/src/Utils/macros.h index 015f9b981..4b765f0d7 100644 --- a/src/Utils/macros.h +++ b/src/Utils/macros.h @@ -81,8 +81,10 @@ void end(); #endif #if INFO -#define dbg_info(...) \ - { printf(__VA_ARGS__); } +#define dbg_info(...) \ + { \ + printf(__VA_ARGS__); \ + } #else #define dbg_info(...) ; #endif @@ -98,8 +100,10 @@ void end(); #endif #if WARN -#define dbg_warn(...) \ - { printf(__VA_ARGS__); } +#define dbg_warn(...) \ + { \ + printf(__VA_ARGS__); \ + } #else #define dbg_warn(...) ; #endif diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index c5dab7d2a..c672c7fd2 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -43,7 +43,7 @@ void bindSocketToAddress(int socket_fd, struct sockaddr_in address) { } struct sockaddr_in createAddress(int port) { - struct sockaddr_in address {}; + struct sockaddr_in address{}; address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(port); @@ -167,7 +167,7 @@ ssize_t WebSocket::read(void *out, size_t size) { } void sendAlarm() { - struct sigaction sact {}; + struct sigaction sact{}; sigemptyset(&sact.sa_mask); sact.sa_flags = 0; sigaction(SIGALRM, &sact, nullptr); diff --git a/src/Utils/util.cpp b/src/Utils/util.cpp index 7455bb3fa..e6ab9e639 100644 --- a/src/Utils/util.cpp +++ b/src/Utils/util.cpp @@ -39,7 +39,83 @@ StackValue *readArgs(Type function, uint8_t *data) { return args; } -// Little endian base (LED128) +// Little endian base (LEB128) + +uint64_t size_leb(uint64_t val) { + uint64_t count = 0; + do { + val >>= 7; + count++; + } while (val != 0); + return count; +} + +uint32_t write_LEB_(uint8_t *dest, uint64_t val) { + uint32_t count = 0; + + do { + uint8_t byte = val & 0x7f; + val >>= 7; + + if (val != 0) byte |= 0x80; + + dest[count++] = byte; + } while (val != 0); + + return count; +} + +uint8_t *write_LEB(uint32_t value) { + uint8_t *buffer = + static_cast(calloc(sizeof(uint8_t), size_leb(value))); + write_LEB_(buffer, value); + return buffer; +} + +uint32_t write_LEB_signed(uint8_t *dest, uint64_t val, uint64_t bits) { + uint32_t count = 0; + + do { + uint8_t byte = val & 0x7f; + val >>= 7; + + if (static_cast(val) < 0) { + val |= UINT64_MAX << (bits - 7); // sign extend + } + + if ((val == 0 && static_cast(byte) >= 0) || + (val == static_cast(-1) && + static_cast(byte) < 0)) { + break; + } + byte |= 0x80; + + dest[count++] = byte; + } while (val != 0); + + return count; +} + +uint64_t write_LEB_s(uint64_t value, uint8_t *buff, uint32_t size, + uint32_t bits, bool sign) { + if (size_leb(value) > size) { + return 0; + } + + if (sign) { + return write_LEB_(buff, value); + } else { + return write_LEB_signed(buff, value, bits); + } +} + +uint64_t write_LEB_32(uint32_t value, uint8_t *buff, uint32_t size) { + return write_LEB_s(value, buff, size, 32, false); +} + +uint64_t write_LEB_32_signed(uint32_t value, uint8_t *buff, uint32_t size) { + return write_LEB_s(value, buff, size, 32, true); +} uint64_t read_LEB_(uint8_t **pos, uint32_t maxbits, bool sign) { uint64_t result = 0; @@ -49,7 +125,7 @@ uint64_t read_LEB_(uint8_t **pos, uint32_t maxbits, bool sign) { uint64_t byte; while (true) { - byte = (uint64_t) * *pos; + byte = (uint64_t)**pos; *pos += 1; result |= ((byte & 0x7fu) << shift); shift += 7; @@ -271,6 +347,13 @@ uint16_t read_B16(uint8_t **bytes) { return n; } +uint8_t read_B8(uint8_t **bytes) { + uint8_t *b = *bytes; + uint8_t n = b[0]; + *bytes += 1; + return n; +} + int read_B32_signed(uint8_t **bytes) { uint8_t *b = *bytes; int n = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]; @@ -286,8 +369,17 @@ uint32_t read_L32(uint8_t **bytes) { return n; } // TODO replace with read_LEB_32? If keep Big endian use memcpy? -void chars_as_hexa(unsigned char *dest, unsigned char *source, - uint32_t len_source) { +int slebf(char *dest, uint8_t *source, const int size, const char *end) { + char *cursor = dest; + for (int i = 0; i < size; i++) { + sprintf(cursor, "%02" PRIx8, source[i]); + cursor += 2; + } + sprintf(cursor, "%s", end); + return size; +} + +void chars_as_hexa(char *dest, unsigned char *source, uint32_t len_source) { for (uint32_t i = 0; i < len_source; i++) { unsigned c = source[i] >> 4; unsigned c2 = source[i] & 0xF; diff --git a/src/Utils/util.h b/src/Utils/util.h index b5717be02..11059ebb2 100644 --- a/src/Utils/util.h +++ b/src/Utils/util.h @@ -17,6 +17,32 @@ */ StackValue *readArgs(Type function, uint8_t *data); +uint64_t size_leb(uint64_t val); + +uint8_t *write_LEB(uint32_t value); + +int slebf(char *dest, uint8_t *source, const int size, const char *end = ""); + +uint32_t write_LEB_(uint8_t *dest, uint64_t val); + +/** + * Write a Little endian base value. + * see: https://en.wikipedia.org/wiki/LEB128 + * + * @param value The value to write. + * @param buff The buffer to write to. + * @param size The size of the buffer. + * @param bits The size of the value type (I32, I64) + * @param sign Whether the value should be sign-extended. + * @return The number of bytes written. + */ +uint64_t write_LEB_s(uint64_t value, uint8_t *buff, uint32_t size, + uint32_t bits, bool sign); + +uint64_t write_LEB_32(uint32_t value, uint8_t *buff, uint32_t size); + +uint64_t write_LEB_32_signed(uint32_t value, uint8_t *buff, uint32_t size); + /** * Read a Little endian base value of 32 bits * see: https://en.wikipedia.org/wiki/LEB128 @@ -99,10 +125,10 @@ double wa_fmin(double a, double b); // legacy util functions (todo remove) uint32_t read_B32(uint8_t **bytes); uint16_t read_B16(uint8_t **bytes); +uint8_t read_B8(uint8_t **bytes); int read_B32_signed(uint8_t **bytes); uint32_t read_L32(uint8_t **bytes); -void chars_as_hexa(unsigned char *dest, unsigned char *source, - uint32_t len_source); +void chars_as_hexa(char *dest, unsigned char *source, uint32_t len_source); unsigned short int sizeof_valuetype(uint32_t); diff --git a/src/WARDuino.h b/src/WARDuino.h index 8d04d1605..39bf0d995 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -9,8 +9,8 @@ #include #include "Debug/debugger.h" -#include "Edward/proxy_supervisor.h" #include "Interpreter/interpreter.h" +#include "Oop/proxy_supervisor.h" #include "WARDuino/internals.h" // Constants @@ -71,10 +71,13 @@ struct IOStateElement { typedef struct PrimitiveEntry { const char *name; + uint32_t index; Primitive f; void (*f_reverse)(Module *m, std::vector); void (*f_serialize_state)(std::vector &); - Type t; + char *(*f_forward)(Module *m); + char *(*f_backward)(Module *m); + Type *t; } PrimitiveEntry; class WARDuino { diff --git a/tests/latch/examples/dummy.wast b/tests/latch/examples/dummy.wast new file mode 100644 index 000000000..ce91e63ea --- /dev/null +++ b/tests/latch/examples/dummy.wast @@ -0,0 +1,28 @@ + +(module + ;; Type declarations + (type $int32->int32->int32 (func (param i32 i32) (result i32))) + (type $int32->int32 (func (param i32) (result i32))) + (type $int32->void (func (param i32))) + (type $void->void (func)) + + ;; Imports from the WARDuino VM + (import "env" "dummy" (func $env.dummy (type $int32->int32->int32))) + (import "env" "print_int" (func $env.print_int (type $int32->void))) + + ;; Memory + (memory 1) + + ;; Main function + (func $main (export "main") (type $void->void) + (call $env.dummy (i32.const 32) (i32.const 64)) + (drop) + (call $env.print_int (i32.load (i32.const 32))) + ) + + (func $dummy (export "dummy") (type $int32->int32->int32) + (call $env.dummy (local.get 0) (local.get 1))) + + (func $load (export "load") (type $int32->int32) + (i32.load (local.get 0))) +) diff --git a/tests/latch/package-lock.json b/tests/latch/package-lock.json deleted file mode 100644 index 707ca38d6..000000000 --- a/tests/latch/package-lock.json +++ /dev/null @@ -1,1309 +0,0 @@ -{ - "name": "warduino-testsuite", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "warduino-testsuite", - "version": "1.0.0", - "devDependencies": { - "latch": "file:./latch-0.3.0.tgz", - "mqtt": "^4.3.7", - "serialport": "^10.4.0", - "typescript": "^4.5.5" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@serialport/binding-mock": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", - "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "^1.2.1", - "debug": "^4.3.3" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@serialport/bindings-cpp": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-10.8.0.tgz", - "integrity": "sha512-OMQNJz5kJblbmZN5UgJXLwi2XNtVLxSKmq5VyWuXQVsUIJD4l9UGHnLPqM5LD9u3HPZgDI5w7iYN7gxkQNZJUw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "@serialport/parser-readline": "^10.2.1", - "debug": "^4.3.2", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12.17.0 <13.0 || >=14.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/bindings-interface": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", - "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22 || ^14.13 || >=16" - } - }, - "node_modules/@serialport/parser-byte-length": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-10.5.0.tgz", - "integrity": "sha512-eHhr4lHKboq1OagyaXAqkemQ1XyoqbLQC8XJbvccm95o476TmEdW5d7AElwZV28kWprPW68ZXdGF2VXCkJgS2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-cctalk": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-10.5.0.tgz", - "integrity": "sha512-Iwsdr03xmCKAiibLSr7b3w6ZUTBNiS+PwbDQXdKU/clutXjuoex83XvsOtYVcNZmwJlVNhAUbkG+FJzWwIa4DA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-delimiter": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-10.5.0.tgz", - "integrity": "sha512-/uR/yT3jmrcwnl2FJU/2ySvwgo5+XpksDUR4NF/nwTS5i3CcuKS+FKi/tLzy1k8F+rCx5JzpiK+koqPqOUWArA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-inter-byte-timeout": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.5.0.tgz", - "integrity": "sha512-WPvVlSx98HmmUF9jjK6y9mMp3Wnv6JQA0cUxLeZBgS74TibOuYG3fuUxUWGJALgAXotOYMxfXSezJ/vSnQrkhQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-packet-length": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-10.5.0.tgz", - "integrity": "sha512-jkpC/8w4/gUBRa2Teyn7URv1D7T//0lGj27/4u9AojpDVXsR6dtdcTG7b7dNirXDlOrSLvvN7aS5/GNaRlEByw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@serialport/parser-readline": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-10.5.0.tgz", - "integrity": "sha512-0aXJknodcl94W9zSjvU+sLdXiyEG2rqjQmvBWZCr8wJZjWEtv3RgrnYiWq4i2OTOyC8C/oPK8ZjpBjQptRsoJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@serialport/parser-delimiter": "10.5.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-ready": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-10.5.0.tgz", - "integrity": "sha512-QIf65LTvUoxqWWHBpgYOL+soldLIIyD1bwuWelukem2yDZVWwEjR288cLQ558BgYxH4U+jLAQahhqoyN1I7BaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-regex": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-10.5.0.tgz", - "integrity": "sha512-9jnr9+PCxRoLjtGs7uxwsFqvho+rxuJlW6ZWSB7oqfzshEZWXtTJgJRgac/RuLft4hRlrmRz5XU40i3uoL4HKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-slip-encoder": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.5.0.tgz", - "integrity": "sha512-wP8m+uXQdkWSa//3n+VvfjLthlabwd9NiG6kegf0fYweLWio8j4pJRL7t9eTh2Lbc7zdxuO0r8ducFzO0m8CQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/parser-spacepacket": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-10.5.0.tgz", - "integrity": "sha512-BEZ/HAEMwOd8xfuJSeI/823IR/jtnThovh7ils90rXD4DPL1ZmrP4abAIEktwe42RobZjIPfA4PaVfyO0Fjfhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@serialport/stream": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-10.5.0.tgz", - "integrity": "sha512-gbcUdvq9Kyv2HsnywS7QjnEB28g+6OGB5Z8TLP7X+UPpoMIWoUsoQIq5Kt0ZTgMoWn3JGM2lqwTsSHF+1qhniA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@serialport/bindings-interface": "1.2.2", - "debug": "^4.3.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", - "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "leven": "^2.1.0", - "minimist": "^1.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/help-me": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", - "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.1.6", - "readable-stream": "^3.6.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/latch": { - "version": "0.3.0", - "resolved": "file:latch-0.3.0.tgz", - "integrity": "sha512-4ZVbuSUb5lmSvcNWfGDnxrOUoFq7uTL62CvfglTunjPig5r5f0daTWd76CwdylxQobInUH3RVXSx8qIZ1HjTmA==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.3", - "ieee754": "^1.2.1", - "ora": "^8.0.1", - "source-map": "^0.7.4", - "ts-node": "^10.5.0" - }, - "bin": { - "latch": "npx ts-node" - } - }, - "node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mqtt": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.8.tgz", - "integrity": "sha512-2xT75uYa0kiPEF/PE0VPdavmEkoBzMT/UL9moid0rAvlCtV48qBwxD62m7Ld/4j8tSkIO1E/iqRl/S72SEOhOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commist": "^1.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "lru-cache": "^6.0.0", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "number-allocator": "^1.0.9", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", - "reinterval": "^1.1.0", - "rfdc": "^1.3.0", - "split2": "^3.1.0", - "ws": "^7.5.5", - "xtend": "^4.0.2" - }, - "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", - "process-nextick-args": "^2.0.1" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", - "dev": true, - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/number-allocator": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", - "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.1", - "js-sdsl": "4.3.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.0.tgz", - "integrity": "sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^5.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.2", - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reinterval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", - "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/serialport": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/serialport/-/serialport-10.5.0.tgz", - "integrity": "sha512-7OYLDsu5i6bbv3lU81pGy076xe0JwpK6b49G6RjNvGibstUqQkI+I3/X491yBGtf4gaqUdOgoU1/5KZ/XxL4dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@serialport/binding-mock": "10.2.2", - "@serialport/bindings-cpp": "10.8.0", - "@serialport/parser-byte-length": "10.5.0", - "@serialport/parser-cctalk": "10.5.0", - "@serialport/parser-delimiter": "10.5.0", - "@serialport/parser-inter-byte-timeout": "10.5.0", - "@serialport/parser-packet-length": "10.5.0", - "@serialport/parser-readline": "10.5.0", - "@serialport/parser-ready": "10.5.0", - "@serialport/parser-regex": "10.5.0", - "@serialport/parser-slip-encoder": "10.5.0", - "@serialport/parser-spacepacket": "10.5.0", - "@serialport/stream": "10.5.0", - "debug": "^4.3.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/serialport/donate" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - } - } -} diff --git a/tests/latch/package.json b/tests/latch/package.json index a1fd84ae5..4b8ee5491 100644 --- a/tests/latch/package.json +++ b/tests/latch/package.json @@ -1,16 +1,16 @@ { - "name": "warduino-testsuite", - "version": "1.0.0", - "scripts": { - "debugtest": "npx ts-node ./src/debugger.test.ts", - "primtest": "npx ts-node ./src/primitives.test.ts", - "spectest": "npx ts-node ./src/spec.test.ts", - "comptest": "npx ts-node ./src/comp.test.ts" - }, - "devDependencies": { - "latch": "file:./latch-0.3.1.tgz", - "mqtt": "^4.3.7", - "serialport": "^10.4.0", - "typescript": "^4.5.5" - } + "name": "warduino-testsuite", + "version": "1.0.0", + "scripts": { + "debugtest": "npx ts-node ./src/debugger.test.ts", + "primtest": "npx ts-node ./src/primitives.test.ts", + "spectest": "npx ts-node ./src/spec.test.ts", + "comptest": "npx ts-node ./src/comp.test.ts" + }, + "devDependencies": { + "latch": "file:./latch-0.3.1.tgz", + "mqtt": "^4.3.7", + "serialport": "^10.4.0", + "typescript": "^4.5.5" + } } diff --git a/tests/latch/src/debugger.test.ts b/tests/latch/src/debugger.test.ts index f4df21468..ead2c8c74 100644 --- a/tests/latch/src/debugger.test.ts +++ b/tests/latch/src/debugger.test.ts @@ -13,12 +13,13 @@ import { Message, OutputStyle, Step, Suite, TestScenario, - Breakpoint + Breakpoint, OutofPlaceSpecification, Target, WASM, Invoker } from 'latch'; +import dump = Message.dump; +import step = Message.step; export const EMULATOR: string = process.env.EMULATOR ?? `${require('os').homedir()}/Arduino/libraries/WARDuino/build-emu/wdcli`; - const EXAMPLES: string = `${__dirname}/../examples/`; /** @@ -30,8 +31,8 @@ framework.style(OutputStyle.github); const integration: Suite = framework.suite('Integration tests: Debugger'); // must be called first -integration.testee('emulator [:8500]', new EmulatorSpecification(8500)); -//integration.testee('esp wrover', new ArduinoSpecification('/dev/ttyUSB0', 'esp32:esp32:esp32wrover'), new HybridScheduler(), {timeout: 0}); +integration.testee('emulator [:8500]', new EmulatorSpecification(8500), {timeout: 4000}); +//integration.testee('esp wrover', new ArduinoSpecification('/dev/ttyUSB0', 'esp32:esp32:esp32wrover'), {timeout: 0}); const expectDUMP: Expectation[] = [ {'pc': {kind: 'description', value: Description.defined} as Expected}, @@ -181,30 +182,7 @@ integration.test(dumpFullTest); // Test *run* command -const running: Step[] = [DUMP, { - title: 'Send RUN command', - instruction: {kind: Kind.Request, value: Message.run}, -}, { - title: 'CHECK: execution continues', - instruction: {kind: Kind.Request, value: Message.dump}, - expected: [{ - 'pc': {kind: 'description', value: Description.defined} as Expected - }, { - 'pc': {kind: 'behaviour', value: Behaviour.changed} as Expected - }] -}]; - -integration.test({ - title: 'Test RUN blink', - program: `${EXAMPLES}blink.wast`, - steps: running -}); - -integration.test({ - title: 'Test RUN button', - program: `${EXAMPLES}button.wast`, - steps: running -}); +// todo // Test *pause* command @@ -312,7 +290,6 @@ const stepOverTest: TestScenario = { integration.test(stepOverTest); -// EDWARD tests with mock proxy const dumpEventsTest: TestScenario = { title: 'Test DUMPEvents', @@ -332,4 +309,58 @@ const dumpEventsTest: TestScenario = { integration.test(dumpEventsTest); -framework.run([integration]); +// EDWARD tests + +const oop = framework.suite('Test Out-of-place primitives'); + +oop.testee('supervisor[:8100] - proxy[:8150]', new OutofPlaceSpecification(8100, 8150), {timeout: 20000}); + +oop.test({ + title: `Test store primitive`, + program: `${EXAMPLES}dummy.wast`, + dependencies: [], + steps: [ + { + title: '[supervisor] CHECK: execution at start of main', + instruction: {kind: Kind.Request, value: dump}, + expected: [{'pc': {kind: 'primitive', value: 129} as Expected}] + }, + + { + title: '[proxy] CHECK: execution at start of main', + instruction: {kind: Kind.Request, value: dump}, + expected: [{'pc': {kind: 'primitive', value: 129} as Expected}], + target: Target.proxy + }, + + new Invoker('load', [WASM.i32(32)], WASM.i32(0), Target.proxy), + + { + title: '[supervisor] Send STEP command', + instruction: {kind: Kind.Request, value: step} + }, + + { + title: '[supervisor] Send STEP command', + instruction: {kind: Kind.Request, value: step} + }, + + { + title: '[supervisor] Send STEP command', + instruction: {kind: Kind.Request, value: step} + }, + + { + title: '[supervisor] CHECK: execution took three steps', + instruction: {kind: Kind.Request, value: dump}, + expected: [{'pc': {kind: 'primitive', value: 136} as Expected}] + }, + + new Invoker('load', [WASM.i32(32)], WASM.i32(42), Target.proxy), + + new Invoker('load', [WASM.i32(32)], WASM.i32(42), Target.supervisor) + ] +}); + +framework.run([integration,oop]).then(() => process.exit(0)); + diff --git a/tests/latch/src/primitives.test.ts b/tests/latch/src/primitives.test.ts index be1a4ad81..892e041ab 100644 --- a/tests/latch/src/primitives.test.ts +++ b/tests/latch/src/primitives.test.ts @@ -8,16 +8,42 @@ import { Message, TestScenario, WASM, - awaitBreakpoint, PureAction, OutputStyle, Suite, Assertable, assertable + awaitBreakpoint, PureAction, OutputStyle, Suite, Assertable, assertable, invoke, returns } from 'latch'; import * as mqtt from 'mqtt'; import Type = WASM.Type; import {Breakpoint} from "latch/dist/types/debug/Breakpoint"; +const examples = `${__dirname}/../examples`; + const framework = Framework.getImplementation(); framework.style(OutputStyle.github); -// TODO disclaimer: file is currently disabled until latch supports AS compilation +const dummy: Suite = framework.suite('Integration tests: dummy primitives'); + +dummy.testee('emulator [:8520]', new EmulatorSpecification(8520)); + +const dummyScenario: TestScenario = { + title: 'Test dummy primitives', + program: `${examples}/dummy.wast`, + steps: [{ + title: 'Check: dummy value', + instruction: invoke('dummy', [WASM.i32(32), WASM.i32(64)]), + expected: returns(WASM.i32(32)) + }, { + title: 'Check: value at 32', + instruction: invoke('load', [WASM.i32(32)]), + expected: returns(WASM.i32(42)) + }, { + title: 'Check: value at 48', + instruction: invoke('load', [WASM.i32(48)]), + expected: returns(WASM.i32(42)) + }] +}; + +dummy.test(dummyScenario); + +// TODO disclaimer: rest of the file is currently disabled until latch supports AS compilation const basic: Suite = framework.suite('Integration tests: basic primitives'); @@ -165,4 +191,4 @@ export function listen(topic: string): PureAction { comms.test(scenario); -framework.run([]); +framework.run([dummy]); diff --git a/tutorials/assemblyscript/main/CMakeLists.txt b/tutorials/assemblyscript/main/CMakeLists.txt index 6cd29af40..3989adc99 100644 --- a/tutorials/assemblyscript/main/CMakeLists.txt +++ b/tutorials/assemblyscript/main/CMakeLists.txt @@ -4,9 +4,9 @@ set(SOURCE_FILES ../../../src/Utils/util_arduino.cpp ../../../src/Utils/sockets.cpp ../../../src/Debug/debugger.cpp - ../../../src/Edward/proxy.cpp - ../../../src/Edward/proxy_supervisor.cpp - ../../../src/Edward/RFC.cpp + ../../../src/Oop/proxy.cpp + ../../../src/Oop/proxy_supervisor.cpp + ../../../src/Oop/RFC.cpp ../../../src/Utils/macros.cpp ../../../src/WARDuino/WARDuino.cpp ../../../src/Primitives/emulated.cpp diff --git a/tutorials/wat/main/CMakeLists.txt b/tutorials/wat/main/CMakeLists.txt index 8a775fb6e..51664b3f7 100644 --- a/tutorials/wat/main/CMakeLists.txt +++ b/tutorials/wat/main/CMakeLists.txt @@ -3,9 +3,9 @@ set(SOURCE_FILES ../../../src/Interpreter/instructions.cpp ../../../src/Memory/mem.cpp ../../../src/Primitives/idf.cpp - ../../../src/Edward/proxy.cpp - ../../../src/Edward/proxy_supervisor.cpp - ../../../src/Edward/RFC.cpp + ../../../src/Oop/proxy.cpp + ../../../src/Oop/proxy_supervisor.cpp + ../../../src/Oop/RFC.cpp ../../../src/Utils/macros.cpp ../../../src/Utils/sockets.cpp ../../../src/Utils/util.cpp