1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#include "stdafx.h"
#include "SharedLib.h"
#include "Core/Str.h"
#include "Engine.h"
#include "Exception.h"
namespace storm {
SharedLib::SharedLib(Url *file, LoadedLib lib, EntryFn entry) : lib(lib), world(file->engine().gc) {
EngineFwdUnique unique = {
&SharedLib::cppType,
&SharedLib::cppTemplate,
&SharedLib::getThread,
&SharedLib::getData,
this,
1.0f,
};
SharedLibStart start = {
sizeof(SharedLibStart),
sizeof(SharedLibInfo),
sizeof(EngineFwdShared),
sizeof(EngineFwdUnique),
file->engine(),
engineFwd(),
unique,
};
zeroMem(root);
gcRoot = file->engine().gc.createRoot(&root, sizeof(root) / sizeof(void *));
root.srcDir = file->parent();
ok = (*entry)(&start, &root.info);
}
SharedLib::~SharedLib() {
if (lib != invalidLib)
unloadLibrary(lib);
Gc::destroyRoot(gcRoot);
gcRoot = null;
}
void SharedLib::shutdown() {
if (root.info.shutdownFn)
(*root.info.shutdownFn)(&root.info);
Gc::destroyRoot(gcRoot);
gcRoot = null;
world.clear();
}
SharedLib *SharedLib::prevInstance() {
return (SharedLib *)root.info.previousIdentifier;
}
CppLoader SharedLib::createLoader(Engine &e, Package *into) {
return CppLoader(e, root.info.world, world, into, root.srcDir);
}
SharedLib *SharedLib::load(Url *file) {
const char *entryName = SHORT_STRING(SHARED_LIB_ENTRY);
// Do not load the library unless we actually think we might be able to load something from there!
if (!hasExport(file, entryName))
return null;
LoadedLib lib = loadLibrary(file);
if (lib == invalidLib)
return null;
EntryFn entry = (EntryFn)findLibraryFn(lib, entryName);
if (!entry) {
unloadLibrary(lib);
return null;
}
SharedLib *result = new SharedLib(file, lib, entry);
if (!result->ok) {
PLN(L"Failed loading " << file);
delete result;
return null;
}
return result;
}
Type *SharedLib::cppType(Engine &e, void *lib, Nat id) {
SharedLib *me = (SharedLib *)lib;
return me->world.types[id];
}
Type *SharedLib::cppTemplate(Engine &e, void *lib, Nat id, Nat count, va_list l) {
SharedLib *me = (SharedLib *)lib;
const nat maxCount = 16;
assert(count < maxCount, L"Too many template parameters used: " + ::toS(count) + L" max " + ::toS(maxCount));
TemplateList *tList = me->world.templates[id];
if (!tList)
return null;
Nat params[maxCount];
for (nat i = 0; i < count; i++)
params[i] = va_arg(l, Nat);
return tList->find(params, count);
}
Thread *SharedLib::getThread(Engine &e, void *lib, const DeclThread *decl) {
SharedLib *me = (SharedLib *)lib;
return me->world.threads[decl->identifier];
}
void *SharedLib::getData(Engine &e, void *lib) {
SharedLib *me = (SharedLib *)lib;
return me->root.info.libData;
}
}
|