Esempio n. 1
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             if value != misc.signext(value, self.size):
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Esempio n. 2
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             if value != misc.signext(value, self.size):
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Esempio n. 3
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.size < rffi.sizeof(lltype.Signed):
             if r_uint(value) - self.vmin > self.vrangemax:
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         value = misc.as_long_long(self.space, w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
Esempio n. 4
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             size = self.size
             if size == 1:
                 signextended = misc.signext(value, 1)
             elif size == 2:
                 signextended = misc.signext(value, 2)
             elif size == 4:
                 signextended = misc.signext(value, 4)
             else:
                 raise AssertionError("unsupported size")
             if value != signextended:
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Esempio n. 5
0
def convert_from_object_fficallback(fresult, ll_res, w_res,
                                    encode_result_for_libffi):
    space = fresult.space
    if isinstance(fresult, W_CTypeVoid):
        if not space.is_w(w_res, space.w_None):
            raise oefmt(
                space.w_TypeError,
                "callback with the return type 'void' must return "
                "None")
        return
    #
    small_result = encode_result_for_libffi and fresult.size < SIZE_OF_FFI_ARG
    if small_result and fresult.is_primitive_integer:
        # work work work around a libffi irregularity: for integer return
        # types we have to fill at least a complete 'ffi_arg'-sized result
        # buffer.
        if type(fresult) is W_CTypePrimitiveSigned:
            # It's probably fine to always zero-extend, but you never
            # know: maybe some code somewhere expects a negative
            # 'short' result to be returned into EAX as a 32-bit
            # negative number.  Better safe than sorry.  This code
            # is about that case.  Let's ignore this for enums.
            #
            # do a first conversion only to detect overflows.  This
            # conversion produces stuff that is otherwise ignored.
            fresult.convert_from_object(ll_res, w_res)
            #
            # manual inlining and tweaking of
            # W_CTypePrimitiveSigned.convert_from_object() in order
            # to write a whole 'ffi_arg'.
            value = misc.as_long(space, w_res)
            misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
            return
        else:
            # zero extension: fill the '*result' with zeros, and (on big-
            # endian machines) correct the 'result' pointer to write to
            misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
            if BIG_ENDIAN:
                diff = SIZE_OF_FFI_ARG - fresult.size
                ll_res = rffi.ptradd(ll_res, diff)
    #
    fresult.convert_from_object(ll_res, w_res)
Esempio n. 6
0
def convert_from_object_fficallback(fresult, ll_res, w_res,
                                    encode_result_for_libffi):
    space = fresult.space
    if isinstance(fresult, W_CTypeVoid):
        if not space.is_w(w_res, space.w_None):
            raise oefmt(space.w_TypeError,
                        "callback with the return type 'void' must return "
                        "None")
        return
    #
    small_result = encode_result_for_libffi and fresult.size < SIZE_OF_FFI_ARG
    if small_result and fresult.is_primitive_integer:
        # work work work around a libffi irregularity: for integer return
        # types we have to fill at least a complete 'ffi_arg'-sized result
        # buffer.
        if type(fresult) is W_CTypePrimitiveSigned:
            # It's probably fine to always zero-extend, but you never
            # know: maybe some code somewhere expects a negative
            # 'short' result to be returned into EAX as a 32-bit
            # negative number.  Better safe than sorry.  This code
            # is about that case.  Let's ignore this for enums.
            #
            # do a first conversion only to detect overflows.  This
            # conversion produces stuff that is otherwise ignored.
            fresult.convert_from_object(ll_res, w_res)
            #
            # manual inlining and tweaking of
            # W_CTypePrimitiveSigned.convert_from_object() in order
            # to write a whole 'ffi_arg'.
            value = misc.as_long(space, w_res)
            misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
            return
        else:
            # zero extension: fill the '*result' with zeros, and (on big-
            # endian machines) correct the 'result' pointer to write to
            misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
            if BIG_ENDIAN:
                diff = SIZE_OF_FFI_ARG - fresult.size
                ll_res = rffi.ptradd(ll_res, diff)
    #
    fresult.convert_from_object(ll_res, w_res)