コード例 #1
0
    def handle_stdarg_h(self, state):
        state.typedefs["va_list"] = CTypedef(name="va_list",
                                             type=CVariadicArgsType())

        def va_start(v, dummy_last):
            assert isinstance(v, Helpers.VarArgs)
            v.idx = 0

        def va_end(v):
            assert isinstance(v, Helpers.VarArgs)
            #assert v.idx == len(v.args), "VarArgs: va_end: not handled all args"  # is this an error?
        def __va_arg(v, inplace_typed):
            assert isinstance(v, Helpers.VarArgs)
            x = v.get_next()
            helpers = v.intp.helpers
            helpers.assignGeneric(inplace_typed, x)
            return inplace_typed

        def __va_arg_getReturnType(stateStruct, stmnt_args):
            assert len(stmnt_args) == 2  # see __va_arg
            return getValueType(stateStruct, stmnt_args[1])

        state.funcs["va_start"] = CWrapValue(va_start,
                                             name="va_start",
                                             returnType=CVoidType)
        state.funcs["va_end"] = CWrapValue(va_end,
                                           name="va_end",
                                           returnType=CVoidType)
        state.macros["va_arg"] = Macro(args=("list", "type"),
                                       rightside="((__va_arg(list, type())))")
        state.funcs["__va_arg"] = CWrapValue(
            __va_arg,
            name="__va_arg",
            returnType=None,
            getReturnType=__va_arg_getReturnType)
コード例 #2
0
 def handle_signal_h(self, state):
     # typedef void (*sig_t) (int)
     state.typedefs["sig_t"] = CTypedef(
         name="sig_t", type=CFuncPointerDecl(type=CVoidType(), args=[CBuiltinType(("int",))]))
     # There is no safe way to support the native C function.
     # The signal handler can be called at any point and it could be that
     # the GIL is hold. Then the signal handler code deadlocks because it also wants the GIL.
     #wrapCFunc(state, "signal", restype=state.typedefs["sig_t"],
     #		  argtypes=(ctypes.c_int, state.typedefs["sig_t"]))
     def signal(sig, f):
         sig = sig.value
         import signal
         if isinstance(f, CWrapValue):
             f = f.value
         def sig_handler(sig, stack_frame):
             return f(sig)
         if isinstance(f, ctypes._CFuncPtr):
             if _ctype_ptr_get_value(f) == 0:  # place-holder for SIG_DFL
                 sig_handler = signal.SIG_DFL
             elif _ctype_ptr_get_value(f) == 1:  # place-holder for SIG_IGN
                 sig_handler = signal.SIG_IGN
         old_action = signal.signal(sig, sig_handler)
         # TODO: need to use helpers.makeFuncPtr for old_action.
         # And maybe handle SIG_DFL/SIG_IGN cases?
         return 0  # place-holder for SIG_DFL
     state.funcs["signal"] = CWrapValue(signal, name="signal", returnType=state.typedefs["sig_t"])
     state.macros["SIGINT"] = Macro(rightside="2")
     state.macros["SIG_DFL"] = Macro(rightside="((sig_t)0)")
     state.macros["SIG_IGN"] = Macro(rightside="((sig_t)1)")
     state.macros["SIG_ERR"] = Macro(rightside="((sig_t)-1)")
コード例 #3
0
    def handle_assert_h(self, state):
        def assert_wrap(x):
            if isinstance(x,
                          (ctypes._Pointer, ctypes.Array, ctypes._CFuncPtr)):
                x = ctypes.cast(x, ctypes.c_void_p)
            assert x.value

        state.funcs["assert"] = CWrapValue(assert_wrap,
                                           returnType=CVoidType,
                                           name="assert")
コード例 #4
0
 def handle_stdio_h(self, state):
     state.macros["NULL"] = Macro(rightside="0")
     FileP = CPointerType(CStdIntType("FILE")).getCType(state)
     wrapCFunc(state, "fopen", restype=FileP, argtypes=(ctypes.c_char_p, ctypes.c_char_p))
     wrapCFunc(state, "fclose", restype=ctypes.c_int, argtypes=(FileP,))
     wrapCFunc(state, "fdopen", restype=FileP, argtypes=(ctypes.c_int, ctypes.c_char_p))
     if sys.platform == "darwin":
         sym_names = ("__stdinp", "__stdoutp", "__stderrp")
     else:
         sym_names = ("stdin", "stdout", "stderr")
     state.vars["stdin"] = CWrapValue(FileP.in_dll(libc, sym_names[0]), name="stdin")
     state.vars["stdout"] = CWrapValue(FileP.in_dll(libc, sym_names[1]), name="stdout")
     state.vars["stderr"] = CWrapValue(FileP.in_dll(libc, sym_names[2]), name="stderr")
     wrapCFunc(state, "printf", restype=ctypes.c_int, argtypes=(ctypes.c_char_p,), varargs=True)
     wrapCFunc(state, "fprintf", restype=ctypes.c_int, argtypes=(FileP, ctypes.c_char_p), varargs=True)
     wrapCFunc(state, "sprintf", restype=ctypes.c_int, argtypes=(ctypes.c_char_p, ctypes.c_char_p), varargs=True)
     wrapCFunc_varargs(state, "vprintf", wrap_funcname="printf")
     wrapCFunc_varargs(state, "vfprintf", wrap_funcname="fprintf")
     wrapCFunc_varargs(state, "vsprintf", wrap_funcname="sprintf")
     wrapCFunc(state, "fputs", restype=ctypes.c_int, argtypes=(ctypes.c_char_p, FileP))
     wrapCFunc(state, "fputc", restype=ctypes.c_int, argtypes=(ctypes.c_int, FileP))
     wrapCFunc(state, "fgets", restype=ctypes.c_char_p, argtypes=(ctypes.c_char_p, ctypes.c_int, FileP))
     wrapCFunc(state, "fread", restype=ctypes.c_size_t, argtypes=(ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, FileP))
     wrapCFunc(state, "fwrite", restype=ctypes.c_size_t, argtypes=(ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, FileP))
     wrapCFunc(state, "fflush", restype=ctypes.c_int, argtypes=(FileP,))
     wrapCFunc(state, "ftell", restype=ctypes.c_long, argtypes=(FileP,))
     wrapCFunc(state, "rewind", restype=CVoidType, argtypes=(FileP,))
     wrapCFunc(state, "ferror", restype=ctypes.c_int, argtypes=(FileP,))
     wrapCFunc(state, "clearerr", restype=CVoidType, argtypes=(FileP,))
     state.vars["errno"] = CWrapValue(0, name="errno") # TODO
     state.macros["EOF"] = Macro(rightside="-1") # TODO?
     wrapCFunc(state, "setbuf", restype=CVoidType, argtypes=(FileP, ctypes.c_char_p))
     wrapCFunc(state, "isatty", restype=ctypes.c_int, argtypes=(ctypes.c_int,))
     wrapCFunc(state, "fileno", restype=ctypes.c_int, argtypes=(FileP,))
     wrapCFunc(state, "getc", restype=ctypes.c_int, argtypes=(FileP,))
     wrapCFunc(state, "ungetc", restype=ctypes.c_int, argtypes=(ctypes.c_int,FileP))
     struct_stat = state.structs["stat"] = CStruct(name="stat") # TODO
     struct_stat.body = CBody(parent=struct_stat)
     CVarDecl(parent=struct_stat, name="st_mode", type=ctypes.c_int).finalize(state)
     state.funcs["fstat"] = CWrapValue(lambda *args: None, returnType=ctypes.c_int, name="fstat") # TODO
     state.macros["S_IFMT"] = Macro(rightside="0") # TODO
     state.macros["S_IFDIR"] = Macro(rightside="0") # TODO
コード例 #5
0
 def handle_stdlib_h(self, state):
     state.macros["EXIT_SUCCESS"] = Macro(rightside="0")
     state.macros["EXIT_FAILURE"] = Macro(rightside="1")
     wrapCFunc(state, "abort", restype=CVoidType, argtypes=())
     wrapCFunc(state, "exit", restype=CVoidType, argtypes=(ctypes.c_int, ))
     wrapCFunc(state,
               "malloc",
               restype=ctypes.c_void_p,
               argtypes=(ctypes.c_size_t, ))
     wrapCFunc(state,
               "free",
               restype=CVoidType,
               argtypes=(ctypes.c_void_p, ))
     state.funcs["atoi"] = CWrapValue(
         lambda x: ctypes.c_int(int(ctypes.cast(x, ctypes.c_char_p).value)),
         returnType=ctypes.c_int)
     state.funcs["getenv"] = CWrapValue(lambda x: _fixCArg(
         ctypes.c_char_p(os.getenv(ctypes.cast(x, ctypes.c_char_p).value))),
                                        returnType=CPointerType(
                                            ctypes.c_byte))
コード例 #6
0
def wrapCFunc(state, funcname, restype=None, argtypes=None):
    f = getattr(ctypes.pythonapi, funcname)
    if restype is None: restype = ctypes.c_int
    if restype is CVoidType:
        f.restype = None
    elif restype is not None:
        f.restype = restype = _fixCType(restype, wrap=True)
    if argtypes is not None:
        f.argtypes = map(_fixCType, argtypes)
    state.funcs[funcname] = CWrapValue(f,
                                       funcname=funcname,
                                       returnType=restype)
コード例 #7
0
def wrapCFunc(state, funcname, restype, argtypes, varargs=False):
    f = getattr(libc, funcname)
    restype = _fixCType(state, restype)
    if restype is CVoidType:
        f.restype = None
    else:
        assert restype is not None
        f.restype = getCTypeWrapped(restype, state)
    assert argtypes is not None
    argtypes = [_fixCType(state, arg) for arg in argtypes]
    f.argtypes = [getCTypeWrapped(arg, state) for arg in argtypes]
    state.funcs[funcname] = CWrapValue(
        f, name=funcname, funcname=funcname,
        returnType=restype, argTypes=argtypes)
コード例 #8
0
def wrapCFunc_varargs(state, funcname, wrap_funcname):
    """
    :param str funcname: e.g. "vprintf"
    :param wrap_funcname: e.g. "printf"
    Will register a new function, where the last arg is expected to be va_list.
    va_list is just a tuple of args.
    Will call the wrap-func with all args and unwraps the va_list args.
    """
    wrap_func = state.funcs[wrap_funcname]
    assert isinstance(wrap_func, CWrapValue)
    wrap_arg_len = len(wrap_func.value.argtypes)
    def f(*args):
        assert len(args) == wrap_arg_len + 1
        assert isinstance(args[-1], Helpers.VarArgs)
        return wrap_func.value(*(args[:-1] + args[-1].args))
    f.__name__ = funcname
    state.funcs[funcname] = CWrapValue(
        f, name=funcname, funcname=funcname,
        returnType=wrap_func.returnType, argTypes=wrap_func.argTypes)
コード例 #9
0
 def handle_stdlib_h(self, state):
     state.macros["EXIT_SUCCESS"] = Macro(rightside="0")
     state.macros["EXIT_FAILURE"] = Macro(rightside="1")
     state.funcs["abort"] = CWrapValue(
         lambda: self.interpreter._abort(),
         returnType=CVoidType,
         name="abort"
     )
     state.funcs["exit"] = CWrapValue(
         lambda s: self.interpreter._exit(s.value),  # int
         returnType=CVoidType,
         name="exit"
     )
     state.funcs["malloc"] = CWrapValue(
         lambda s: self.interpreter._malloc(s.value),  # size_t
         returnType=ctypes.c_void_p,
         name="malloc"
     )
     state.funcs["realloc"] = CWrapValue(
         lambda ps: self.interpreter._realloc(_ctype_ptr_get_value(ps[0]), ps[1].value),  # void*, size_t
         returnType=ctypes.c_void_p,
         name="realloc"
     )
     state.funcs["free"] = CWrapValue(
         lambda p: self.interpreter._free(_ctype_ptr_get_value(p)),  # void*
         returnType=CVoidType,
         name="free"
     )
     wrapCFunc(state, "strtoul", restype=ctypes.c_ulong, argtypes=(ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p), ctypes.c_int))
     state.funcs["atoi"] = CWrapValue(
         lambda x: ctypes.c_int(int(ctypes.cast(x, ctypes.c_char_p).value)),
         returnType=ctypes.c_int,
         name="atoi"
     )
     state.funcs["getenv"] = CWrapValue(
         lambda x: _fixCArg(ctypes.c_char_p(os.getenv(ctypes.cast(x, ctypes.c_char_p).value))),
         returnType=CPointerType(ctypes.c_byte),
         name="getenv"
     )
コード例 #10
0
 def handle_stdio_h(self, state):
     state.macros["NULL"] = Macro(rightside="0")
     wrapCFunc(state,
               "printf",
               restype=ctypes.c_int,
               argtypes=(ctypes.c_char_p, ))
     FileP = CPointerType(CStdIntType("FILE")).getCType(state)
     wrapCFunc(state,
               "fopen",
               restype=FileP,
               argtypes=(ctypes.c_char_p, ctypes.c_char_p))
     wrapCFunc(state, "fclose", restype=ctypes.c_int, argtypes=(FileP, ))
     wrapCFunc(state,
               "fdopen",
               restype=FileP,
               argtypes=(ctypes.c_int, ctypes.c_char_p))
     state.vars["stdin"] = CWrapValue(callCFunc("fdopen", 0, "r"))
     state.vars["stdout"] = CWrapValue(callCFunc("fdopen", 1, "a"))
     state.vars["stderr"] = CWrapValue(callCFunc("fdopen", 2, "a"))
     wrapCFunc(state,
               "fprintf",
               restype=ctypes.c_int,
               argtypes=(FileP, ctypes.c_char_p))
     wrapCFunc(state,
               "fputs",
               restype=ctypes.c_int,
               argtypes=(ctypes.c_char_p, FileP))
     wrapCFunc(state,
               "fgets",
               restype=ctypes.c_char_p,
               argtypes=(ctypes.c_char_p, ctypes.c_int, FileP))
     wrapCFunc(state,
               "fread",
               restype=ctypes.c_size_t,
               argtypes=(ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t,
                         FileP))
     wrapCFunc(state, "fflush", restype=ctypes.c_int, argtypes=(FileP, ))
     wrapCFunc(state, "ftell", restype=ctypes.c_long, argtypes=(FileP, ))
     wrapCFunc(state, "rewind", restype=CVoidType, argtypes=(FileP, ))
     wrapCFunc(state, "ferror", restype=ctypes.c_int, argtypes=(FileP, ))
     state.vars["errno"] = CWrapValue(0)  # TODO
     state.macros["EOF"] = Macro(rightside="-1")  # TODO?
     wrapCFunc(state,
               "setbuf",
               restype=CVoidType,
               argtypes=(FileP, ctypes.c_char_p))
     wrapCFunc(state,
               "isatty",
               restype=ctypes.c_int,
               argtypes=(ctypes.c_int, ))
     wrapCFunc(state, "fileno")
     wrapCFunc(state, "getc")
     wrapCFunc(state,
               "ungetc",
               restype=ctypes.c_int,
               argtypes=(ctypes.c_int, FileP))
     struct_stat = state.structs["stat"] = CStruct(name="stat")  # TODO
     struct_stat.body = CBody(parent=struct_stat)
     CVarDecl(parent=struct_stat, name="st_mode",
              type=ctypes.c_int).finalize(state)
     state.funcs["fstat"] = CWrapValue(lambda *args: None,
                                       returnType=ctypes.c_int)  # TODO
     state.macros["S_IFMT"] = Macro(rightside="0")  # TODO
     state.macros["S_IFDIR"] = Macro(rightside="0")  # TODO
コード例 #11
0
    def handle_assert_h(self, state):
        def assert_wrap(x):
            assert x

        state.funcs["assert"] = CWrapValue(assert_wrap)