add binding to dynamiclibrary namespace for multimodule linking

This commit is contained in:
Siu Kwan Lam 2013-07-31 17:50:30 -05:00
commit c0e9dedc90
2 changed files with 51 additions and 0 deletions

View file

@ -195,6 +195,9 @@ class ExecutionEngine(llvm.Wrapper):
ptr = self._ptr.runFunction(fn._ptr, list(map(lambda x: x._ptr, args)))
return GenericValue(ptr)
def get_pointer_to_named_function(self, name, abort=True):
return self._ptr.getPointerToNamedFunction(name, abort)
def get_pointer_to_function(self, fn):
return self._ptr.getPointerToFunction(fn._ptr)
@ -371,3 +374,14 @@ class TargetMachine(llvm.Wrapper):
def feature_string(self):
return self._ptr.getTargetFeatureString()
#===----------------------------------------------------------------------===
# Dynamic Library
#===----------------------------------------------------------------------===
def dylib_add_symbol(name, ptr):
api.llvm.sys.DynamicLibrary.AddSymbol(name, ptr)
def dylib_address_of_symbol(name):
return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(name)

View file

@ -1373,6 +1373,43 @@ class TestMCJIT(TestCase):
callee = CFUNCTYPE(c_int, c_int, c_int)(ptr)
self.assertEqual(321 + 123, callee(321, 123))
def test_multi_module_linking(self):
# generate external library module
m = Module.new('external-library-module')
fnty = Type.function(Type.int(), [Type.int(), Type.int()])
libfname = 'myadd'
func = m.add_function(fnty, libfname)
bb = func.append_basic_block('')
bldr = Builder.new(bb)
bldr.ret(bldr.add(*func.args))
func.verify()
# JIT the lib module and bind dynamic symbol
libengine = EngineBuilder.new(m).mcjit(True).create()
myadd_ptr = libengine.get_pointer_to_function(func)
le.dylib_add_symbol(libfname, myadd_ptr)
# reference external library
m = Module.new('user')
fnty = Type.function(Type.int(), [Type.int(), Type.int()])
func = m.add_function(fnty, 'foo')
bb = func.append_basic_block('')
bldr = Builder.new(bb)
extadd = m.get_or_insert_function(fnty, name=libfname)
bldr.ret(bldr.call(extadd, func.args))
func.verify()
# JIT the user module
engine = EngineBuilder.new(m).mcjit(True).create()
ptr = engine.get_pointer_to_function(func)
self.assertEqual(myadd_ptr,
engine.get_pointer_to_named_function(libfname))
from ctypes import c_int, CFUNCTYPE
callee = CFUNCTYPE(c_int, c_int, c_int)(ptr)
self.assertEqual(321 + 123, callee(321, 123))
if llvm.version >= (3, 3):
# MCJIT broken in 3.2
# The test will segfault in OSX?