Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
libec/ide parsing: Fix for bad memory when opening multiple code edit…
…ors importing a shared library (e.g. eda) that creates objects

- The module classes were being unregistered when the first loaded up file gets closed
- An extra safety module instance now gets loaded and only gets freed when all referencing editors are closed
  • Loading branch information
jerstlouis committed Dec 12, 2011
1 parent 76b19c9 commit daa244a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
34 changes: 34 additions & 0 deletions compiler/libec/src/freeAst.ec
Expand Up @@ -1143,6 +1143,40 @@ void FreeModuleData(Module module)
if(function.symbol)
FreeSymbol(function.symbol);
}

// Free the extra module instance on closing the last code editor using it
if(!inCompiler)
{
MapIterator <String, List<Module> > mapIt { map = loadedModules };
while(mapIt.Next())
{
List<Module> list = mapIt.data;
Iterator<Module> it { list };
bool found = false;
while(it.Next())
{
if(it.data == module)
{
list.Remove(it.pointer);
found = true;
break;
}
}
if(found)
{
if(list.count == 1)
{
// Unload the initial module that we loaded for safe sharing
Module mod = list[0];
list.Remove(list.GetFirst());
loadedModules.Remove(mapIt.pointer);
delete list;
eModule_Unload(__thisModule, mod);
}
break;
}
}
}
}

public void FreeTypeData(Module privateModule)
Expand Down
38 changes: 34 additions & 4 deletions compiler/libec/src/loadSymbols.ec
Expand Up @@ -718,6 +718,8 @@ public bool LoadSymbols(char * fileName, ImportType importType, bool loadDllOnly
return globalInstance;
}

Map<String, List<Module> > loadedModules { };

// (Same function as in actual compiler)
public void ImportModule(char * name, ImportType importType, AccessMode importAccess, bool loadDllOnly)
{
Expand Down Expand Up @@ -776,15 +778,43 @@ public void ImportModule(char * name, ImportType importType, AccessMode importAc

if(ext[0] || !FileExists(symFile))
{
bool skipLoad = false;
List<Module> list = null;

char file[MAX_FILENAME];
strcpy(file, name);
StripExtension(file);

loadedModule = eModule_LoadStrict(privateModule, file, importAccess);
if(loadedModule)
// Load an extra instance of any shared module to ensure freeing up a
// module loaded in another file will not invalidate our objects.
if(!inCompiler)
{
loadedModule.importType = importType;
module.dllOnly = false; // If this is truly a dll, no need to reload it again...
Iterator<List<Module> > it { loadedModules };
if(!it.Index(file, false))
{
Module firstModule = eModule_LoadStrict(__thisModule, file, importAccess);
if(firstModule)
{
list = { };
list.Add(firstModule);
loadedModules[file] = list;
}
else
skipLoad = true;
}
else
list = it.data;
}

if(!skipLoad)
{
loadedModule = eModule_LoadStrict(privateModule, file, importAccess);
if(loadedModule)
{
loadedModule.importType = importType;
module.dllOnly = false; // If this is truly a dll, no need to reload it again...
if(list) list.Add(loadedModule);
}
}
}
}
Expand Down

0 comments on commit daa244a

Please sign in to comment.