← index #9114Issue #7782
Related · high · value 0.504
QUERY · ISSUE

Viper bug: integers > 0x3fffffff appear as python objects

openby rkompassopened 2022-08-26updated 2023-04-16
bug

The bug presumably is a result of the same logic as the now closed #8956 (perhaps the fix is also as simple).

Integers outside the mpy small int range ( > 0x3fffffff) are handled as python objects in viper.
This rather should happen with integers > 0xffffffff.

Code to illustrate the issue:

# @micropython.viper
# def largeint(a) -> int:
#     b = a & 0xfffffffe
#     return b                   #  ->  ViperTypeError: return expected 'int' but got 'object'

# print(largeint(3))

@micropython.viper
def largeint2(a):
    b = a & 0xfffffffe           #      works, but b is now a python object rather than a viper integer
    return b

print(largeint2(3))


gv = b'\x03\x00\x00\x00'

@micropython.viper
def and32(p:ptr32):
    p[0] = p[0] & 0xfffffffe              # -> ViperTypeError: can't do binary op between 'int' and 'object'
                                          # but  works with 0x3ffffffe and with int(0xfffffffe)

print('Before: ', int.from_bytes(gv, 'little'))   #  -> 3
and32(gv) 
print('After: ', int.from_bytes(gv, 'little'))    # should be 2, but does not work
CANDIDATE · ISSUE

Bug in viper code calculations involving two operands which are indexed values

closedby rkompassopened 2021-09-13updated 2021-09-14
bugpy-core

I found the following code to produce wrong results, both on the pyboard and the unix version (mpy v1.17).

@micropython.viper
def vtest1(gv:ptr16) -> int:
    gv[0] += gv[1]<<1  # does gv[0] = gv[1] * 3 instead
    return gv[0]   # the same error occurs with gv:ptr18 and gv:ptr32 in vtest1

gv = b'\x03\x00\x02\x01'
print('vtest1(gv): ', vtest1(gv), '    correct: 519') 

Output:
vtest1(gv): 774 correct: 519

A followup investigation revealed that the core of the issue seems to be the combination of two operands like gv[0] and gv[1]. Where

@micropython.viper
def vtest2(a:int, b:int) -> int:
    c = a-b            # correct
    return c

print('vtest2(19, 5): ', vtest2(19, 5), '    correct: 14')
print('vtest2(5, 19): ', vtest2(5, 19), '    correct: -14')

@micropython.viper
def vtest3(gv:ptr16, a:int) -> int:
    c = gv[1] - a            # correct
    return c

@micropython.viper
def vtest4(gv:ptr16, a:int) -> int:
    c = a - gv[1]            # correct
    return c

gv = b'\x03\x00\x02\x01'
print('vtest3(gv, 19): ', vtest3(gv, 19), '    correct: 239')
gv = b'\x03\x00\x02\x01'
print('vtest4(gv, 19): ', vtest4(gv, 19), '    correct: -239')

produce the correct results: Output:

vtest2(19, 5):  14     correct: 14
vtest2(5, 19):  -14     correct: -14
vtest3(gv, 19):  239     correct: 239
vtest4(gv, 19):  -239     correct: -239

The combination of two indexed values seems to deliver wrong results:

@micropython.viper
def vtest5(gv:ptr16) -> int:
    c = gv[0] - gv[1]            # wrong: 0
    return c

@micropython.viper
def vtest6(gv:ptr16) -> int:
    c = gv[1] - gv[0]            # wrong: 0
    return c

gv = b'\x03\x00\x02\x01'
print('vtest5(gv): ', vtest5(gv), '    correct: -255')
gv = b'\x03\x00\x02\x01'
print('vtest6(gv): ', vtest6(gv), '    correct: 255')

@micropython.viper
def vtest7(gv:ptr16) -> int:
    c = gv[0] + gv[1]            # wrong
    return c

@micropython.viper
def vtest8(gv:ptr16) -> int:
    c = gv[1] + gv[0]            # wrong
    return c

gv = b'\x03\x00\x02\x01'
print('vtest7(gv): ', vtest7(gv), '    correct: 261')
gv = b'\x03\x00\x02\x01'
print('vtest8(gv): ', vtest8(gv), '    correct: 261')

Output:

vtest5(gv):  0     correct: -255
vtest6(gv):  0     correct: 255
vtest7(gv):  516     correct: 261
vtest8(gv):  6     correct: 261

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied