Skip to content

Commit

Permalink
ext/MiniScript: synced MiniScript
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasdr committed Jan 11, 2024
1 parent 58d753b commit 899fb9d
Show file tree
Hide file tree
Showing 36 changed files with 232 additions and 47 deletions.
1 change: 0 additions & 1 deletion ext/miniscript/src/miniscript/miniscript/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Context::~Context() {
scriptsById.clear();
}


void Context::addScript(const string& id, MiniScript* script) {
if (scriptsById.find(id) != scriptsById.end()) {
Console::println("An error occurred: a script with id " + id + " is already registered");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ using _Console = miniscript::utilities::Console;
using _HTTPDownloadClient = miniscript::network::httpclient::HTTPDownloadClient;

const string HTTPDownloadClientClass::TYPE_NAME = "HTTPDownloadClient";
vector<shared_ptr<_HTTPDownloadClient>> HTTPDownloadClientClass::instances;

void HTTPDownloadClientClass::initialize() {
}
Expand All @@ -44,7 +43,11 @@ void HTTPDownloadClientClass::registerMethods(MiniScript* miniScript) const {
return "HTTPDownloadClient";
}
void executeMethod(span<MiniScript::Variable>& arguments, MiniScript::Variable& returnValue, const MiniScript::Statement& statement) override {
auto& scriptContext = *static_cast<HTTPDownloadClientClass::ScriptContext*>(miniScript->getDataTypeScriptContext(MiniScript::TYPE_HTTPDOWNLOADCLIENT));
//
auto httpDownloadClient = make_shared<_HTTPDownloadClient>();
scriptContext.instances.push_back(httpDownloadClient);
//
returnValue.setType(MiniScript::TYPE_HTTPDOWNLOADCLIENT);
returnValue.setValue(&httpDownloadClient);
}
Expand Down Expand Up @@ -296,9 +299,7 @@ void HTTPDownloadClientClass::unsetVariableValue(MiniScript::Variable& variable)
}

void HTTPDownloadClientClass::setVariableValue(MiniScript::Variable& variable) const {
auto sharedPtr = make_shared<_HTTPDownloadClient>();
instances.push_back(sharedPtr);
variable.setValuePtr(new shared_ptr<_HTTPDownloadClient>(sharedPtr));
variable.setValuePtr(new shared_ptr<_HTTPDownloadClient>(nullptr));
}

void HTTPDownloadClientClass::setVariableValue(MiniScript::Variable& variable, const void* value) const {
Expand Down Expand Up @@ -335,3 +336,22 @@ const string HTTPDownloadClientClass::getValueAsString(const MiniScript::Variabl
return "HTTPDownloadClientClass(url: " + httpDownloadClient->getURL() + ", file: " + httpDownloadClient->getFile() + ")";
}

void* HTTPDownloadClientClass::createScriptContext() const {
return new ScriptContext();
}

void HTTPDownloadClientClass::deleteScriptContext(void* context) const {
delete static_cast<ScriptContext*>(context);
}

void HTTPDownloadClientClass::garbageCollection(void* context) const {
auto& scriptContext = *static_cast<ScriptContext*>(context);
for (auto i = 0; i < scriptContext.instances.size(); i++) {
auto& instance = scriptContext.instances[i];
if (instance.use_count() == 1 && instance->isFinished() == true) {
instance->join();
scriptContext.instances.erase(scriptContext.instances.begin() + i);
i--;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ using _HTTPDownloadClient = miniscript::network::httpclient::HTTPDownloadClient;
class miniscript::miniscript::HTTPDownloadClientClass final: public MiniScript::DataType {
private:
MINISCRIPT_STATIC_DLL_IMPEXT static const string TYPE_NAME;
MINISCRIPT_STATIC_DLL_IMPEXT static vector<shared_ptr<_HTTPDownloadClient>> instances;

// overridden methods
void registerConstants(MiniScript* miniScript) const override;
Expand All @@ -37,8 +36,18 @@ class miniscript::miniscript::HTTPDownloadClientClass final: public MiniScript::
bool div(MiniScript* miniScript, const span<MiniScript::Variable>& arguments, MiniScript::Variable& returnValue, const MiniScript::Statement& statement) const override;
bool add(MiniScript* miniScript, const span<MiniScript::Variable>& arguments, MiniScript::Variable& returnValue, const MiniScript::Statement& statement) const override;
bool sub(MiniScript* miniScript, const span<MiniScript::Variable>& arguments, MiniScript::Variable& returnValue, const MiniScript::Statement& statement) const override;
void* createScriptContext() const override;
void deleteScriptContext(void* context) const override;
void garbageCollection(void* context) const override;

public:
/**
* Script context
*/
struct ScriptContext {
vector<shared_ptr<_HTTPDownloadClient>> instances;
};

// forbid class copy
FORBID_CLASS_COPY(HTTPDownloadClientClass)

Expand Down
16 changes: 16 additions & 0 deletions ext/miniscript/src/miniscript/miniscript/MiniScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ const vector<string> MiniScript::getTranspilationUnits() {
}

MiniScript::MiniScript() {
for (auto datatype: dataTypes) dataTypeScriptContexts.push_back(datatype->createScriptContext());
setNative(false);
pushScriptState();
}
Expand All @@ -172,6 +173,9 @@ MiniScript::~MiniScript() {
for (const auto& [methodName, method]: this->methods) delete method;
for (const auto& [stateMachineStateId, stateMachineState]: this->stateMachineStates) delete stateMachineState;
while (scriptStateStack.empty() == false) popScriptState();
garbageCollection();
for (auto i = 0; i < dataTypes.size(); i++) dataTypes[i]->deleteScriptContext(dataTypeScriptContexts[i]);
dataTypeScriptContexts.clear();
}

void MiniScript::registerStateMachineState(StateMachineState* state) {
Expand Down Expand Up @@ -1152,6 +1156,9 @@ void MiniScript::execute() {

// execute while having statements to be processed
executeStateMachine();

// try garbage collection
tryGarbageCollection();
}

const string MiniScript::getNextStatement(const string& scriptCode, int& i, int& line) {
Expand Down Expand Up @@ -2469,6 +2476,8 @@ bool MiniScript::call(int scriptIdx, span<Variable>& arguments, Variable& return
}
// done, pop the function script state
popScriptState();
// try garbage collection
tryGarbageCollection();
//
return true;
}
Expand Down Expand Up @@ -2904,6 +2913,9 @@ void MiniScript::registerMethods() {
callArgumentIdx++;
}
}
} else {
_Console::println(miniScript->getStatementInformation(statement) + ": class/object member not found: " + member + "()");
miniScript->startErrorScript();
}
} else {
_Console::println(getMethodName() + "(): " + miniScript->getStatementInformation(statement) + ": argument mismatch: expected arguments: " + miniScript->getArgumentInformation(getMethodName()) + ": invalid variable type");
Expand Down Expand Up @@ -4093,3 +4105,7 @@ void MiniScript::setConstant(Variable& variable) {
break;
}
}

void MiniScript::garbageCollection() {
for (auto i = 0; i < dataTypes.size(); i++) dataTypes[i]->garbageCollection(dataTypeScriptContexts[i]);
}
67 changes: 62 additions & 5 deletions ext/miniscript/src/miniscript/miniscript/MiniScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class miniscript::miniscript::MiniScript {
friend class MathMethods;

protected:
//
bool mathDataType { false };
MiniScript::VariableType type { TYPE_NULL };

Expand Down Expand Up @@ -263,6 +264,24 @@ class miniscript::miniscript::MiniScript {
*/
virtual bool sub(MiniScript* miniScript, const span<MiniScript::Variable>& arguments, MiniScript::Variable& returnValue, const MiniScript::Statement& statement) const = 0;

/**
* Create script context
* @return script context
*/
virtual void* createScriptContext() const = 0;

/**
* Delete script context
* @param context script context
*/
virtual void deleteScriptContext(void* context) const = 0;

/**
* Issue garbage collection
* @param context script context
*/
virtual void garbageCollection(void* context) const = 0;

public:
// forbid class copy
FORBID_CLASS_COPY(DataType)
Expand Down Expand Up @@ -809,7 +828,7 @@ class miniscript::miniscript::MiniScript {
// custom data type
auto dataTypeIdx = static_cast<int>(from.getType()) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("ScriptVariable::copyScriptVariable(): unknown custom data type with id " + to_string(dataTypeIdx));
_Console::println("ScriptVariable::copyScriptVariable(): unknown data type with id " + to_string(dataTypeIdx));
return;
}
MiniScript::dataTypes[dataTypeIdx]->copyVariable(to, from);
Expand Down Expand Up @@ -997,7 +1016,7 @@ class miniscript::miniscript::MiniScript {
// custom data type
auto dataTypeIdx = static_cast<int>(this->getType()) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("ScriptVariable::setType(): unknown custom data type with id " + to_string(dataTypeIdx));
_Console::println("ScriptVariable::setType(): unknown data type with id " + to_string(dataTypeIdx));
return;
}
MiniScript::dataTypes[dataTypeIdx]->unsetVariableValue(*this);
Expand Down Expand Up @@ -1053,7 +1072,7 @@ class miniscript::miniscript::MiniScript {
// custom data type
auto dataTypeIdx = static_cast<int>(this->getType()) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("ScriptVariable::setType(): unknown custom data type with id " + to_string(dataTypeIdx));
_Console::println("ScriptVariable::setType(): unknown data type with id " + to_string(dataTypeIdx));
return;
}
MiniScript::dataTypes[dataTypeIdx]->setVariableValue(*this);
Expand Down Expand Up @@ -1358,7 +1377,7 @@ class miniscript::miniscript::MiniScript {
// custom data type
auto dataTypeIdx = static_cast<int>(this->getType()) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("ScriptVariable::setValue(): unknown custom data type with id " + to_string(dataTypeIdx));
_Console::println("ScriptVariable::setValue(): unknown data type with id " + to_string(dataTypeIdx));
return;
}
MiniScript::dataTypes[dataTypeIdx]->setVariableValue(*this, value);
Expand Down Expand Up @@ -2105,7 +2124,7 @@ class miniscript::miniscript::MiniScript {
// custom data types
auto dataTypeIdx = static_cast<int>(getType()) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("ScriptVariable::getValueAsString(): unknown custom data type with id " + to_string(dataTypeIdx));
_Console::println("ScriptVariable::getValueAsString(): unknown data type with id " + to_string(dataTypeIdx));
return result;
}
return MiniScript::dataTypes[dataTypeIdx]->getValueAsString(*this);
Expand Down Expand Up @@ -2617,6 +2636,8 @@ class miniscript::miniscript::MiniScript {
inline void stopScriptExecution() {
while (scriptStateStack.size() > 1) popScriptState();
//
garbageCollection();
//
auto& scriptState = getScriptState();
//
scriptState.running = false;
Expand Down Expand Up @@ -2701,8 +2722,25 @@ class miniscript::miniscript::MiniScript {
*/
static const Variable initializeMapSet(const string_view& initializerString, MiniScript* miniScript, const Statement& statement);

/**
* Try garbage collection
*/
inline void tryGarbageCollection() {
auto now = _Time::getCurrentMillis();
if (dataTypesGCTime == -1ll || now - dataTypesGCTime >= GARBAGE_COLLECTION_INTERVAL) {
garbageCollection();
dataTypesGCTime = now;
}
}

/**
* Issue garbage collection
*/
void garbageCollection();

private:
static constexpr bool VERBOSE { false };
static constexpr int64_t GARBAGE_COLLECTION_INTERVAL { 1000ll };

/**
* Shutdown RAII
Expand Down Expand Up @@ -2731,6 +2769,8 @@ class miniscript::miniscript::MiniScript {
MINISCRIPT_STATIC_DLL_IMPEXT static vector<DataType*> dataTypes;
MINISCRIPT_STATIC_DLL_IMPEXT static ShutdownRAII shutdownRAII;

//
int64_t dataTypesGCTime { -1ll };

// TODO: maybe we need a better naming for this
// functions defined by script itself
Expand All @@ -2747,6 +2787,8 @@ class miniscript::miniscript::MiniScript {
//
bool scriptValid { false };

vector<void*> dataTypeScriptContexts;

/**
* Parse script code into this MiniScript instance
* @param scriptCode script code
Expand Down Expand Up @@ -3096,6 +3138,21 @@ class miniscript::miniscript::MiniScript {
*/
static void setConstant(Variable& variable);

/**
* Return data type script context
* @param type data type
* @return data type script context
*/
inline void* getDataTypeScriptContext(VariableType type) {
// custom data types
auto dataTypeIdx = static_cast<int>(type) - TYPE_PSEUDO_DATATYPES;
if (dataTypeIdx < 0 || dataTypeIdx >= MiniScript::dataTypes.size()) {
_Console::println("MiniScript::getDataTypeScriptContext(): unknown data type with id " + to_string(dataTypeIdx));
return nullptr;
}
return MiniScript::dataTypeScriptContexts[dataTypeIdx];
}

/**
* @return context
*/
Expand Down
2 changes: 2 additions & 0 deletions ext/miniscript/src/miniscript/miniscript/Transpiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ void Transpiler::transpile(MiniScript* miniScript, const string& transpilationFi
generatedDeclarations+= headerIndent + "\t" + "}" + "\n";
generatedDeclarations+= headerIndent + "\t" + "if (getScriptState().running == false) return;" + "\n";
generatedDeclarations+= headerIndent + "\t" + "executeStateMachine();" + "\n";
generatedDeclarations+= headerIndent + "\t" + "// try garbage collection" + "\n";
generatedDeclarations+= headerIndent + "\t" + "tryGarbageCollection();" + "\n";
generatedDeclarations+= headerIndent + "}" + "\n";
generatedDeclarations+= "\n";
generatedDeclarations+= string() + "protected:" + "\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ void HTTPDownloadClient::start() {
socket->shutdown();

//
downloadClient->finished = true;
downloadClient->progress = 1.0f;
downloadClient->finished = true;
} catch (Exception& exception) {
if (socket != nullptr) socket->shutdown();
downloadClient->finished = true;
Expand Down
11 changes: 5 additions & 6 deletions ext/miniscript/src/miniscript/tools/miniscript-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ static void printInformation() {
Console::println();
Console::println("If you do not provide a path to the script or do not pipe a script into the standard input stream,");
Console::println("you get a prompt to enter your script. You can finish inputting by hitting Ctrl-D on Unix or Ctrl-Z on Windows.");
exit(EXIT_FAILURE);
}

int main(int argc, char** argv)
Expand All @@ -56,7 +55,7 @@ int main(int argc, char** argv)
string argument = argv[i];
if (argument == "--help") {
printInformation();
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
} else
if (argument == "--version") {
version = true;
Expand All @@ -66,7 +65,7 @@ int main(int argc, char** argv)
} else {
if (pathToScript.empty() == false) {
Console::println("Path to script already given");
exit(EXIT_FAILURE);
return EXIT_FAILURE;
} else {
pathToScript = argument;
}
Expand All @@ -77,7 +76,7 @@ int main(int argc, char** argv)
if (version == true) {
Console::println(string("miniscript ") + Version::getVersion());
Console::println(Version::getCopyright());
exit(EXIT_FAILURE);
return EXIT_FAILURE;
}

//
Expand Down Expand Up @@ -159,7 +158,7 @@ int main(int argc, char** argv)
} else
if (version == false) {
printInformation();
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}

// delete temporary file if we have created any
Expand All @@ -176,5 +175,5 @@ int main(int argc, char** argv)
}

//
exit(script == nullptr || script->isValid() == false?EXIT_FAILURE:EXIT_SUCCESS);
return script == nullptr || script->isValid() == false?EXIT_FAILURE:EXIT_SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@ int main(int argc, char** argv)
Console::println();

//
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ int main(int argc, char** argv)
Generator::generateLibrary(scriptClassPairs, libraryURI);

//
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
Loading

0 comments on commit 899fb9d

Please sign in to comment.