File: call-jit-ctypes.py

package info (click to toggle)
llvm-py 0.5%2Bsvn85-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 996 kB
  • ctags: 1,768
  • sloc: python: 3,655; ansic: 1,893; cpp: 495; pascal: 91; makefile: 8; sh: 1
file content (64 lines) | stat: -rwxr-xr-x 2,065 bytes parent folder | download
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
#!/usr/bin/env python

from llvm.core import Module,Type,Builder,ModuleProvider
from llvm.ee import ExecutionEngine
import llvm.core
import ctypes

def test_jit_ctypes():

    # This example demonstrates calling an LLVM defined function using
    # ctypes. It illustrates the common C pattern of having an output
    # variable in the argument list to the function. The function also
    # returns an error code upon exit.

    # setup llvm types
    ty_errcode = Type.int()
    ty_float = Type.float()
    ty_ptr_float = Type.pointer(Type.float())
    ty_func = Type.function(ty_errcode, [ty_float, ty_float, ty_ptr_float])

    # setup ctypes types
    ct_errcode = ctypes.c_int
    ct_float = ctypes.c_float
    ct_ptr_float = ctypes.POINTER(ct_float)
    ct_argtypes = [ct_float, ct_float, ct_ptr_float]

    # generate the function using LLVM
    my_module = Module.new('my_module')

    mult = my_module.add_function(ty_func, "mult")
    mult.args[0].name = "a"
    mult.args[1].name = "b"
    mult.args[2].name = "out"
    mult.args[2].add_attribute(llvm.core.ATTR_NO_CAPTURE) # add nocapture to output arg
    mult.does_not_throw = True # add nounwind attribute to function

    bb = mult.append_basic_block("entry")
    builder = Builder.new(bb)
    tmp = builder.mul( mult.args[0], mult.args[1] )
    builder.store( tmp, mult.args[2] )
    builder.ret(llvm.core.Constant.int(ty_errcode, 0))

    if 0:
        # print the created module
        print my_module

    # compile the function
    mp = ModuleProvider.new(my_module)
    ee = ExecutionEngine.new(mp)

    # let ctypes know about the function
    func_ptr_int = ee.get_pointer_to_function( mult )
    FUNC_TYPE = ctypes.CFUNCTYPE(ct_errcode, *ct_argtypes)
    py_mult = FUNC_TYPE(func_ptr_int)

    # now run the function, calling via ctypes
    output_value = ct_float(123456.0)
    errcode = py_mult( 2.0, 3.0, ctypes.byref(output_value) )
    if errcode != 0:
        raise RuntimeError('unexpected error')
    assert output_value.value == 6.0

if __name__=='__main__':
    test_jit_ctypes()