@@ -103,14 +103,43 @@ Object.extend(Squeak.Primitives.prototype,
103
103
104
104
ffiModules : { } , // map library name to module name
105
105
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
+
106
126
ffiDoCallout : function ( argCount , extLibFunc , stArgs ) {
107
127
this . ffi_lastError = Squeak . FFIErrorGenericError ;
108
128
var libName = extLibFunc . pointers [ Squeak . ExtLibFunc_module ] . bytesAsString ( ) ;
109
129
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
+ }
110
140
111
141
if ( ! libName ) libName = "libc" ; // default to libc
112
142
113
- var modName = this . ffiModules [ libName ] ;
114
143
if ( modName === undefined ) {
115
144
if ( ! Squeak . externalModules [ libName ] ) {
116
145
var prefixes = [ "" , "lib" ] ;
0 commit comments