Skip to content

Commit b6b62eb

Browse files
committed
[ffi] support external addresses for funcs
1 parent 46eaa93 commit b6b62eb

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

vm.plugins.ffi.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,43 @@ Object.extend(Squeak.Primitives.prototype,
103103

104104
ffiModules: {}, // map library name to module name
105105

106+
ffiFuncs: [], // functions loaded via dlsym (index + 1 is handle)
107+
108+
// create an external address as handle for a function dynamically
109+
// this is a hook for other modules equivalent to dlsym() in C.
110+
// Later we can retrieve the module and func by handle
111+
ffiLookupFunc: function(mod, funcName) {
112+
var handle = this.ffiFuncs.findIndex(func => func.funcName === funcName) + 1;
113+
if (!handle) {
114+
if (!mod[funcName]) return 0;
115+
// we could keep a reverse map, but this is not time-critical
116+
var modName = Object.keys(this.loadedModules).find(name => this.loadedModules[name] === mod);
117+
if (modName === undefined) throw Error("FFI: module not loaded?! " + mod.getModuleName());
118+
var libName = Object.keys(this.ffiModules).find(name => this.ffiModules[name] === modName);
119+
if (libName === undefined) throw Error("FFI: library not found?! " + mod.getModuleName());
120+
this.ffiFuncs.push({libName: libName, modName: modName, funcName: funcName});
121+
handle = this.ffiFuncs.length;
122+
}
123+
return handle;
124+
},
125+
106126
ffiDoCallout: function(argCount, extLibFunc, stArgs) {
107127
this.ffi_lastError = Squeak.FFIErrorGenericError;
108128
var libName = extLibFunc.pointers[Squeak.ExtLibFunc_module].bytesAsString();
109129
var funcName = extLibFunc.pointers[Squeak.ExtLibFunc_name].bytesAsString();
130+
var funcAddr = extLibFunc.pointers[Squeak.ExtLibFunc_handle].wordsOrBytes()[0];
131+
var modName = this.ffiModules[libName];
132+
133+
if (funcAddr) {
134+
var func = this.ffiFuncs[funcAddr];
135+
if (!func) throw Error("FFI: not a valid External Address: " + funcAddr);
136+
libName = func.libName;
137+
modName = func.modName;
138+
funcName = func.funcName;
139+
}
110140

111141
if (!libName) libName = "libc"; // default to libc
112142

113-
var modName = this.ffiModules[libName];
114143
if (modName === undefined) {
115144
if (!Squeak.externalModules[libName]) {
116145
var prefixes = ["", "lib"];

0 commit comments

Comments
 (0)