* intnum.c (yasm_intnum_create_sized): New, reverse function of

yasm_intnum_get_sized().
* intnum.h (yasm_intnum_create_sized): Prototype.

* yasm.pyx: Bring in _PyLong_From/AsByteArray functions.
* intnum.pyx: Use yasm_intnum_create_sized(), etc to implement full 128-bit
number handling.

* intnum.c (yasm_intnum_get_str): Return strings in hex rather than in
decimal.

svn path=/trunk/yasm/; revision=1488
0.5.0
Peter Johnson 19 years ago
parent 8909d99167
commit bbf23a557d
  1. 65
      libyasm/intnum.c
  2. 14
      libyasm/intnum.h
  3. 27
      tools/python-yasm/intnum.pxi
  4. 22
      tools/python-yasm/yasm.pyx

@ -296,6 +296,44 @@ yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
return intn;
}
yasm_intnum *
yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize,
int bigendian, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
unsigned long i = 0;
intn->origsize = 0;
if (srcsize*8 > BITVECT_NATIVE_SIZE)
yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
/* Read the buffer into a bitvect */
BitVector_Empty(conv_bv);
if (bigendian) {
/* TODO */
yasm_internal_error(N_("big endian not implemented"));
} else {
for (i = 0; i < srcsize; i++)
BitVector_Chunk_Store(conv_bv, 8, i*8, ptr[i]);
}
/* Sign extend if needed */
if (srcsize*8 < BITVECT_NATIVE_SIZE && sign && (ptr[i] & 0x80) == 0x80)
BitVector_Interval_Fill(conv_bv, i*8, BITVECT_NATIVE_SIZE-1);
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
} else {
intn->type = INTNUM_BV;
intn->val.bv = BitVector_Clone(conv_bv);
}
return intn;
}
yasm_intnum *
yasm_intnum_copy(const yasm_intnum *intn)
{
@ -881,17 +919,30 @@ yasm_size_uleb128(unsigned long v)
char *
yasm_intnum_get_str(const yasm_intnum *intn)
{
unsigned char *s;
char *s, *s2;
switch (intn->type) {
case INTNUM_UL:
s = yasm_xmalloc(16);
sprintf((char *)s, "%lu", intn->val.ul);
return (char *)s;
break;
s = yasm_xmalloc(20);
sprintf(s, "0x%lx", intn->val.ul);
return s;
case INTNUM_BV:
return (char *)BitVector_to_Dec(intn->val.bv);
break;
if (BitVector_msb_(intn->val.bv)) {
/* it's negative: negate the bitvector to get positive */
BitVector_Negate(conv_bv, intn->val.bv);
s2 = (char *)BitVector_to_Hex(conv_bv);
s = yasm_xmalloc(strlen(s2)+4);
strcpy(s, "-0x");
strcat(s, s2);
yasm_xfree(s2);
} else {
s2 = (char *)BitVector_to_Hex(intn->val.bv);
s = yasm_xmalloc(strlen(s2)+3);
strcpy(s, "0x");
strcat(s, s2);
yasm_xfree(s2);
}
return s;
}
/*@notreached@*/
return NULL;

@ -92,7 +92,7 @@ void yasm_intnum_cleanup(void);
/** Create a new intnum from LEB128-encoded form.
* \param ptr pointer to start of LEB128 encoded form
* \param sign signed (1) or unsiged (0) LEB128 format
* \param sign signed (1) or unsigned (0) LEB128 format
* \param size number of bytes read from ptr (output)
* \param line virtual line (where the number came from)
* \return Newly allocated intnum. Number of bytes read returned into
@ -102,6 +102,18 @@ void yasm_intnum_cleanup(void);
(const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size,
unsigned long line);
/** Create a new intnum from a little-endian or big-endian buffer.
* In little endian, the LSB is in ptr[0].
* \param ptr pointer to start of buffer
* \param sign signed (1) or unsigned (0) source
* \param srcsize source buffer size (in bytes)
* \param bigendian endianness (nonzero=big, zero=little)
* \param line virtual line; may be 0 if warn is 0
*/
/*@only@*/ yasm_intnum *yasm_intnum_create_sized
(unsigned char *ptr, int sign, size_t srcsize, int bigendian,
unsigned long line);
/** Duplicate an intnum.
* \param intn intnum
* \return Newly allocated intnum with the same value as intn.

@ -36,6 +36,8 @@ cdef extern from "libyasm/intnum.h":
cdef yasm_intnum *yasm_intnum_create_int(long i)
cdef yasm_intnum *yasm_intnum_create_leb128(unsigned char *ptr,
int sign, unsigned long *size, unsigned long line)
cdef yasm_intnum *yasm_intnum_create_sized(unsigned char *ptr, int sign,
size_t srcsize, int bigendian, unsigned long line)
cdef yasm_intnum *yasm_intnum_copy(yasm_intnum *intn)
cdef void yasm_intnum_destroy(yasm_intnum *intn)
cdef void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op,
@ -63,11 +65,12 @@ cdef extern from "libyasm/intnum.h":
cdef unsigned long yasm_size_uleb128(unsigned long v)
cdef void yasm_intnum_print(yasm_intnum *intn, FILE *f)
# TODO: rework __new__ / __int__ / __long__ to support > int values
cdef class IntNum:
cdef yasm_intnum *intn
def __new__(self, value, base=None):
cdef unsigned char buf[16]
self.intn = NULL
if isinstance(value, IntNum):
@ -79,29 +82,29 @@ cdef class IntNum:
val = None
if isinstance(value, str):
val = int(value, base)
val = long(value, base)
elif isinstance(value, (int, long)):
val = value
val = long(value)
if val is None:
raise ValueError
if val < 0:
self.intn = yasm_intnum_create_int(val)
else:
self.intn = yasm_intnum_create_uint(val)
_PyLong_AsByteArray(val, buf, 16, 1, 1)
self.intn = yasm_intnum_create_sized(buf, 1, 16, 0, 0)
def __dealloc__(self):
if self.intn != NULL: yasm_intnum_destroy(self.intn)
def __long__(self):
cdef unsigned char buf[16]
yasm_intnum_get_sized(self.intn, buf, 16, 128, 0, 0, 0, 0)
return _PyLong_FromByteArray(buf, 16, 1, 1)
def __int__(self):
if yasm_intnum_sign(self.intn) < 0:
return yasm_intnum_get_int(self.intn)
else:
return yasm_intnum_get_uint(self.intn)
return int(self.__long__())
def __repr__(self):
return str(int(self))
return "IntNum(%s)" % str(int(self))
def __op(self, op, o=None):
lhs = IntNum(self)

@ -22,6 +22,23 @@
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""Interface to the Yasm library.
The Yasm library (aka libyasm) provides the core functionality of the Yasm
assembler. Classes in this library provide for manipulation of machine
instructions and object file constructs such as symbol tables and sections.
Expression objects encapsulate complex expressions containing registers,
symbols, and operations such as SEG.
Bytecode objects encapsulate data or code objects such as data, reserve,
align, or instructions.
Section objects encapsulate an object file section, including the section
name, any Bytecode objects contained within that section, and other
information.
"""
cdef extern from "Python.h":
cdef object PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
@ -31,6 +48,11 @@ cdef extern from "Python.h":
cdef void *PyCObject_AsVoidPtr(object)
cdef void *PyCObject_GetDesc(object)
cdef object _PyLong_FromByteArray(unsigned char *bytes, unsigned int n,
int little_endian, int is_signed)
cdef int _PyLong_AsByteArray(object v, unsigned char *bytes, unsigned int n,
int little_endian, int is_signed) except -1
cdef extern from "libyasm/compat-queue.h":
pass

Loading…
Cancel
Save