Description
I would like to be able to dynamically load a mod from inside a platform type of x-cli-*
(such as x-cli-win
), similar to how microcontrollers can place a mod in the flash xs
partition and on reboot have the host and mod available for importing modules. My goal here is to dynamically load a mod from a cloud server, and execute it on both microcontrollers and x-cli-*
platforms.
I have gotten the x-cli-win
platform working, with my own custom main.c
file as follows (all from cut/paste of various code from Moddable):
/*
* Copyright (c) 2016-2020 Moddable Tech, Inc.
*
* This file is part of the Moddable SDK Runtime.
*
* The Moddable SDK Runtime is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Moddable SDK Runtime is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "xsAll.h"
#include "mc.xs.h"
extern txPreparation* xsPreparation;
#define xsFindResult(_THIS,_ID) fxFindResult(the, &_THIS, _ID)
xsBooleanValue fxFindResult(xsMachine* the, xsSlot* slot, xsIndex id)
{
xsBooleanValue result;
xsOverflow(-1);
fxPush(*slot);
if (fxHasID(the, id)) {
fxPush(*slot);
fxGetID(the, id);
xsResult = *the->stack;
the->stack++;
result = 1;
}
else
result = 0;
return result;
}
int main(int argc, char* argv[])
{
static txMachine root;
int error = 0;
txMachine* machine = &root;
txPreparation* preparation = xsPreparation();
c_memset(machine, 0, sizeof(txMachine));
machine->preparation = preparation;
machine->keyArray = preparation->keys;
machine->keyCount = (txID)preparation->keyCount + (txID)preparation->creation.keyCount;
machine->keyIndex = (txID)preparation->keyCount;
machine->nameModulo = preparation->nameModulo;
machine->nameTable = preparation->names;
machine->symbolModulo = preparation->symbolModulo;
machine->symbolTable = preparation->symbols;
machine->stack = &preparation->stack[0];
machine->stackBottom = &preparation->stack[0];
machine->stackTop = &preparation->stack[preparation->stackCount];
machine->firstHeap = &preparation->heap[0];
machine->freeHeap = &preparation->heap[preparation->heapCount - 1];
machine->aliasCount = (txID)preparation->aliasCount;
machine = fxCloneMachine(&preparation->creation, machine, "tool", NULL);
#ifdef mxInstrument
fxDescribeInstrumentation(machine, 0, NULL, NULL);
#endif
xsBeginHost(machine);
{
xsVars(2);
#ifdef mxInstrument
fxSampleInstrumentation(the, 0, NULL);
#endif
{
xsTry {
xsVar(1) = xsAwaitImport("main", XS_IMPORT_DEFAULT);
if (xsTest(xsVar(1))) {
if (xsIsInstanceOf(xsVar(1), xsFunctionPrototype)) {
xsCallFunction0(xsVar(1), xsGlobal);
}
else if (xsFindResult(xsVar(1), xsID_onLaunch)) {
xsCallFunction0(xsResult, xsVar(1));
}
}
}
xsCatch {
xsStringValue message = xsToString(xsException);
fprintf(stderr, "### %s\n", message);
error = 1;
}
}
}
xsEndHost(the);
xsDeleteMachine(machine);
return error;
}
void fxAbort(xsMachine* the, int status) {
exit(status);
}
I don't understand what the fxCloneMachine
call does, but my gut is I need to add some logic following that call, and before I attempt to import the module(s) using xsAwaitImport
. My immediate goal is Windows, but I'll eventually need it to operate on Mac and Linux as well.
Any hints on what I should be looking at to do this? I see in the Windows simulator (simulator/win/main.cpp
line 698, in fxScreenViewProc
handling the WM_LAUNCH_MACHINE
message) that it seems to open the file and map the file into memory space (CreateFileMapping
and MapViewOfFile
). Mac and Linux do something similar, but using mmap
instead. After this, it goes into the Simulator fxScreenLaunch
method (build/simulator/screen.c
line 241) that seems to do some work with xsPreparation
, fxMapArchive
, and fxPrepareMachine
that seem like they may be the trick to pulling all this together?