How to load knums from bytecode?

  • From: xorloser <xorloser@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Mon, 10 Sep 2018 18:30:20 +1000

Hi all

I am writing some python3 code where I am attempting to replicate the
printing of a lua-jit bytecode listing as done by a call to:
luajit -bl somefile.raw

I have it working correctly in most cases except for the handling of knums
(the constant float number values). I have 2 issues with knums:


1) My code produces slightly different values for some numbers. I assume
this is due to rounding errors, though surely it should be possible to
replicate how luajit is doing it so that I can get the exact same results?
The following examples show the luajit listing first, followed by my
listing:

0007    KNUM     6   0      ; 0.8
0007    KNUM     6   0      ; 0.8000000000009095

0066    KNUM     4   0      ; 0.4
0067    KNUM     5   1      ; 0.43
0068    KNUM     6   0      ; 0.4
0066    KNUM     4   0      ; 0.40000000000045477
0067    KNUM     5   1      ; 0.43
0068    KNUM     6   0      ; 0.40000000000045477

0076    KNUM     5   2      ; 0.3843137254902
0077    KNUM     6   3      ; 0.74117647058824
0076    KNUM     5   2      ; 0.38431372549065085
0077    KNUM     6   3      ; 0.7411764854893965

0075    KNUM    14   0      ; 0.05
0075    KNUM    14   0      ; 0.050000000000056846


2) The other issue I have is where my code generates vastly different
numbers. I can only assume that luajit is doing some special in these cases
that I am missing.

0053    TSETM    5   1      ; 1
0053    TSETM    5   1      ; 4503599627370497.0

0009    TSETM    1   0      ; 2
0009    TSETM    1   0      ; 4503599627370498.0

It may help to post the hex values of these here:
4503599627370497 == 0x00100000_00000001
4503599627370498 == 0x00100000_00000002

Also when loading these values from bytecode, the initial values loaded in
are:
hi=0x43300000, lo=0x00000001
hi=0x43300000, lo=0x00000002
I added some prints into the luajit sourcecode to confirm that I have
parsed these correctly from the bytecode. They are the same values that the
luajit source spits out via its calls to bcread_uleb128_33() and
bcread_uleb128() so I don't think my issue is at this point.

I then pack these two hi and lo values into consecutive 32bit unsigned
ints, and then unpack the resulting 64bits as a 64bit double. That is when
I get the results of:
hi=0x43300000, lo=0x00000001 --> 4503599627370497.0 (ie 0x00100000_00000001)
hi=0x43300000, lo=0x00000002 --> 4503599627370498.0 (ie 0x00100000_00000002)

I do this same pack/unpack conversion for other values which are either
correct off by the small rounding error mentioned in #1.


Can anyone help me fix these two issues? :)

thx
xor

Other related posts:

  • » How to load knums from bytecode? - xorloser