Fix various lua bugs to prevent crashes

pull/170/head
James Ball 2023-09-11 21:28:34 +01:00
rodzic 19c115e47a
commit 60e7e2082d
5 zmienionych plików z 52 dodań i 17 usunięć

Wyświetl plik

@ -187,11 +187,17 @@ void OscirenderAudioProcessorEditor::updateCodeEditor() {
codeEditors[i]->setVisible(false);
}
codeEditors[index]->setVisible(true);
// used so that codeDocumentTextInserted and codeDocumentTextDeleted know whether the parserLock
// is held by the message thread or not. We hold the lock in this function, but not when the
// code document is updated by the user editing text. Since both functions are called by the
// message thread, this is safe.
updatingDocumentsWithParserLock = true;
if (index == 0) {
codeEditors[index]->loadContent(audioProcessor.perspectiveEffect->getCode());
} else {
codeEditors[index]->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(originalIndex), false).readEntireStreamAsString());
}
updatingDocumentsWithParserLock = false;
}
triggerAsyncUpdate();
}
@ -227,12 +233,22 @@ void OscirenderAudioProcessorEditor::editPerspectiveFunction(bool enable) {
// parsersLock AND effectsLock must be locked before calling this function
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
updateCodeDocument();
if (updatingDocumentsWithParserLock) {
updateCodeDocument();
} else {
juce::SpinLock::ScopedLockType parserLock(audioProcessor.parsersLock);
updateCodeDocument();
}
}
// parsersLock AND effectsLock must be locked before calling this function
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
updateCodeDocument();
if (updatingDocumentsWithParserLock) {
updateCodeDocument();
} else {
juce::SpinLock::ScopedLockType parserLock(audioProcessor.parsersLock);
updateCodeDocument();
}
}
// parsersLock AND effectsLock must be locked before calling this function

Wyświetl plik

@ -55,6 +55,8 @@ private:
MainMenuBarModel menuBarModel{*this};
juce::MenuBarComponent menuBar;
std::atomic<bool> updatingDocumentsWithParserLock = false;
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
void updateCodeDocument();

Wyświetl plik

@ -381,10 +381,10 @@ void OscirenderAudioProcessor::changeCurrentFile(int index) {
if (index < 0 || index >= fileBlocks.size()) {
return;
}
changeSound(sounds[index]);
currentFile = index;
updateLuaValues();
updateObjValues();
changeSound(sounds[index]);
}
void OscirenderAudioProcessor::changeSound(ShapeSound::Ptr sound) {

Wyświetl plik

@ -5,6 +5,7 @@
LuaParser::LuaParser(juce::String script) {
// initialization
L = luaL_newstate();
lua_atpanic(L, panic);
luaL_openlibs(L);
this->script = script;
@ -54,24 +55,30 @@ std::vector<float> LuaParser::run() {
lua_geti(L, LUA_REGISTRYINDEX, functionRef);
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
if (ret != 0) {
const char* error = lua_tostring(L, -1);
DBG(error);
functionRef = -1;
} else if (lua_istable(L, -1)) {
auto length = lua_rawlen(L, -1);
if (lua_isfunction(L, -1)) {
const int ret = lua_pcall(L, 0, LUA_MULTRET, 0);
if (ret != 0) {
const char* error = lua_tostring(L, -1);
DBG(error);
functionRef = -1;
} else if (lua_istable(L, -1)) {
auto length = lua_rawlen(L, -1);
for (int i = 1; i <= length; i++) {
lua_pushinteger(L, i);
lua_gettable(L, -2);
float value = lua_tonumber(L, -1);
lua_pop(L, 1);
values.push_back(value);
for (int i = 1; i <= length; i++) {
lua_pushinteger(L, i);
lua_gettable(L, -2);
float value = lua_tonumber(L, -1);
lua_pop(L, 1);
values.push_back(value);
}
}
} else {
DBG("functionRef is not a function");
functionRef = -1;
}
lua_pop(L, 1);
// clear stack
lua_settop(L, 0);
step++;
@ -86,3 +93,11 @@ void LuaParser::setVariable(juce::String variableName, double value) {
variables.push_back(value);
updateVariables = true;
}
int LuaParser::panic(lua_State *L) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "error object is not a string";
DBG("PANIC: unprotected error in call to Lua API (%s)\n" << msg);
return 0; /* return to Lua to abort */
}

Wyświetl plik

@ -14,6 +14,8 @@ public:
private:
void parse();
static int panic(lua_State* L);
int functionRef = -1;
long step = 1;
lua_State* L;