Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Is bytecode machine (in)dependent?

Reply
Thread Tools

Is bytecode machine (in)dependent?

 
 
Robert McLay
Guest
Posts: n/a
 
      10-28-2005
I'm trying to understand bytecodes generated on different machines.
I understand that the bytecodes can change between version. But since
I'm told that .pyc files are version dependent but not machine
dependent, I'm wondering why the bytecodes are machine dependent.

my friend and I created this simple example to explore the problem.
The example code is:

#!/usr/bin/env python
#
import sys, os

def main():
x = 1.234
print x

if ( __name__ == '__main__'):
main()


Using sib.py from Vendorid 1.0 generates different bytecodes under linux
and sgi. At its core sib.py is using:

# Compile the code using prefix and marshall it.
compiled_code = compile(source_code, prefix, 'exec')
marshalled_code = marshal.dumps(compiled_code)

to get the bytecodes.

So why are the byte codes different? Is it that the intel-linux is
little endian and the SGI is big endian and the numerical constant
(1.234) is stored different depending on the endian-ness?


This was generated under intel-linux using python 2.4.2




/*================================================= =========================*/
/* Frozen main script for test */
/* Generated from test.py */
/* This is generated code; Do not modify it! */
/*--------------------------------------------------------------------------*/
unsigned char M___main__[] =
{
99,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,
0,115,55,0,0,0,100,0,0,107,0,0,90,0,0,100,
0,0,107,1,0,90,1,0,100,1,0,132,0,0,90,2,
0,101,3,0,100,2,0,106,2,0,111,11,0,1,101,2,
0,131,0,0,1,110,1,0,1,100,0,0,83,40,3,0,
0,0,78,99,0,0,0,0,1,0,0,0,1,0,0,0,
67,0,0,0,115,15,0,0,0,100,1,0,125,0,0,124,
0,0,71,72,100,0,0,83,40,2,0,0,0,78,102,5,
49,46,50,51,52,40,1,0,0,0,116,1,0,0,0,120,
40,1,0,0,0,82,0,0,0,0,40,0,0,0,0,40,
0,0,0,0,116,23,0,0,0,47,104,111,109,101,47,118, /* This line */
112,97,114,114,47,115,105,98,47,116,101,115,116,46 ,112,121,
116,4,0,0,0,109,97,105,110,5,0,0,0,115,4,0,
0,0,0,1,6,1,116,8,0,0,0,95,95,109,97,105,
110,95,95,40,4,0,0,0,116,3,0,0,0,115,121,115,
116,2,0,0,0,111,115,82,2,0,0,0,116,8,0,0,
0,95,95,110,97,109,101,95,95,40,3,0,0,0,82,4,
0,0,0,82,2,0,0,0,82,5,0,0,0,40,0,0,
0,0,40,0,0,0,0,82,1,0,0,0,116,1,0,0,
0,63,3,0,0,0,115,6,0,0,0,18,2,9,4,13,
1,
}; x

And under SGI (python 2.4.2) it created :

/*================================================= =========================*/
/* Frozen main script for test */
/* Generated from test.py */
/* This is generated code; Do not modify it! */
/*--------------------------------------------------------------------------*/
unsigned char M___main__[] =
{
99,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,
0,115,55,0,0,0,100,0,0,107,0,0,90,0,0,100,
0,0,107,1,0,90,1,0,100,1,0,132,0,0,90,2,
0,101,3,0,100,2,0,106,2,0,111,11,0,1,101,2,
0,131,0,0,1,110,1,0,1,100,0,0,83,40,3,0,
0,0,78,99,0,0,0,0,1,0,0,0,1,0,0,0,
67,0,0,0,115,15,0,0,0,100,1,0,125,0,0,124,
0,0,71,72,100,0,0,83,40,2,0,0,0,78,102,5,
49,46,50,51,52,40,1,0,0,0,116,1,0,0,0,120,
40,1,0,0,0,82,0,0,0,0,40,0,0,0,0,40,
0,0,0,0,116,23,0,0,0,47,87,111,114,107,47,118, /* This line */
112,97,114,114,47,115,105,98,47,116,101,115,116,46 ,112,121,
116,4,0,0,0,109,97,105,110,5,0,0,0,115,4,0,
0,0,0,1,6,1,116,8,0,0,0,95,95,109,97,105,
110,95,95,40,4,0,0,0,116,3,0,0,0,115,121,115,
116,2,0,0,0,111,115,82,2,0,0,0,116,8,0,0,
0,95,95,110,97,109,101,95,95,40,3,0,0,0,82,4,
0,0,0,82,2,0,0,0,82,5,0,0,0,40,0,0,
0,0,40,0,0,0,0,82,1,0,0,0,116,1,0,0,
0,63,3,0,0,0,115,6,0,0,0,18,2,9,4,13,
1,
};


The difference between the two is very slight:

18c18
< 0,0,0,0,116,23,0,0,0,47,104,111,109,101,47,118,
---
> 0,0,0,0,116,23,0,0,0,47,87,111,114,107,47,118,



 
Reply With Quote
 
 
 
 
Tim Peters
Guest
Posts: n/a
 
      10-28-2005
[Robert McLay]
> I'm trying to understand bytecodes generated on different machines.
> I understand that the bytecodes can change between version. But since
> I'm told that .pyc files are version dependent but not machine
> dependent, I'm wondering why the bytecodes are machine dependent.


They aren't -- at least not particularly <wink>.

> my friend and I created this simple example to explore the problem.
> The example code is:
>
> #!/usr/bin/env python
> #
> import sys, os
>
> def main():
> x = 1.234
> print x
>
> if ( __name__ == '__main__'):
> main()
>
>
> Using sib.py from Vendorid 1.0 generates different bytecodes under linux
> and sgi. At its core sib.py is using:
>
> # Compile the code using prefix and marshall it.
> compiled_code = compile(source_code, prefix, 'exec')
> marshalled_code = marshal.dumps(compiled_code)
>
> to get the bytecodes.


Why do you believe that `prefix` had the same value in both runs? The
output suggests it did not, but can't guess more than that from here
since I don't know where `prefix` came from.

> So why are the byte codes different? Is it that the intel-linux is
> little endian and the SGI is big endian


No; marshal format has fixed endianness.

> and the numerical constant (1.234) is stored different depending on the
> endian-ness?


Python defers to the platform C library for string->float conversions,
and it's *possible* that different platforms could convert "1.234" to
a C double in slightly different ways. There's no evidence of that
here, though.

> This was generated under intel-linux using python 2.4.2
>
>
>
>
> /*================================================= =========================*/
> /* Frozen main script for test */
> /* Generated from test.py */
> /* This is generated code; Do not modify it! */
> /*--------------------------------------------------------------------------*/
> unsigned char M___main__[] =
> {
> 99,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,
> 0,115,55,0,0,0,100,0,0,107,0,0,90,0,0,100,
> 0,0,107,1,0,90,1,0,100,1,0,132,0,0,90,2,
> 0,101,3,0,100,2,0,106,2,0,111,11,0,1,101,2,
> 0,131,0,0,1,110,1,0,1,100,0,0,83,40,3,0,
> 0,0,78,99,0,0,0,0,1,0,0,0,1,0,0,0,
> 67,0,0,0,115,15,0,0,0,100,1,0,125,0,0,124,
> 0,0,71,72,100,0,0,83,40,2,0,0,0,78,102,5,
> 49,46,50,51,52,40,1,0,0,0,116,1,0,0,0,120,
> 40,1,0,0,0,82,0,0,0,0,40,0,0,0,0,40,
> 0,0,0,0,116,23,0,0,0,47,104,111,109,101,47,118, /* This line */
> 112,97,114,114,47,115,105,98,47,116,101,115,116,46 ,112,121,
> 116,4,0,0,0,109,97,105,110,5,0,0,0,115,4,0,
> 0,0,0,1,6,1,116,8,0,0,0,95,95,109,97,105,
> 110,95,95,40,4,0,0,0,116,3,0,0,0,115,121,115,
> 116,2,0,0,0,111,115,82,2,0,0,0,116,8,0,0,
> 0,95,95,110,97,109,101,95,95,40,3,0,0,0,82,4,
> 0,0,0,82,2,0,0,0,82,5,0,0,0,40,0,0,
> 0,0,40,0,0,0,0,82,1,0,0,0,116,1,0,0,
> 0,63,3,0,0,0,115,6,0,0,0,18,2,9,4,13,
> 1,
> }; x
>
> And under SGI (python 2.4.2) it created :
>
> /*================================================= =========================*/
> /* Frozen main script for test */
> /* Generated from test.py */
> /* This is generated code; Do not modify it! */
> /*--------------------------------------------------------------------------*/
> unsigned char M___main__[] =
> {
> 99,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,
> 0,115,55,0,0,0,100,0,0,107,0,0,90,0,0,100,
> 0,0,107,1,0,90,1,0,100,1,0,132,0,0,90,2,
> 0,101,3,0,100,2,0,106,2,0,111,11,0,1,101,2,
> 0,131,0,0,1,110,1,0,1,100,0,0,83,40,3,0,
> 0,0,78,99,0,0,0,0,1,0,0,0,1,0,0,0,
> 67,0,0,0,115,15,0,0,0,100,1,0,125,0,0,124,
> 0,0,71,72,100,0,0,83,40,2,0,0,0,78,102,5,
> 49,46,50,51,52,40,1,0,0,0,116,1,0,0,0,120,
> 40,1,0,0,0,82,0,0,0,0,40,0,0,0,0,40,
> 0,0,0,0,116,23,0,0,0,47,87,111,114,107,47,118, /* This line */
> 112,97,114,114,47,115,105,98,47,116,101,115,116,46 ,112,121,
> 116,4,0,0,0,109,97,105,110,5,0,0,0,115,4,0,
> 0,0,0,1,6,1,116,8,0,0,0,95,95,109,97,105,
> 110,95,95,40,4,0,0,0,116,3,0,0,0,115,121,115,
> 116,2,0,0,0,111,115,82,2,0,0,0,116,8,0,0,
> 0,95,95,110,97,109,101,95,95,40,3,0,0,0,82,4,
> 0,0,0,82,2,0,0,0,82,5,0,0,0,40,0,0,
> 0,0,40,0,0,0,0,82,1,0,0,0,116,1,0,0,
> 0,63,3,0,0,0,115,6,0,0,0,18,2,9,4,13,
> 1,
> };
>
>
> The difference between the two is very slight:
>
> 18c18
> < 0,0,0,0,116,23,0,0,0,47,104,111,109,101,47,118,
> ---
> > 0,0,0,0,116,23,0,0,0,47,87,111,114,107,47,118,


Stare at this:

>>> ''.join(map(chr, [47,104,111,109,101,47,118]))

'/home/v'
>>> ''.join(map(chr, [47,87,111,114,107,47,118]))

'/Work/v'

It _suggests_ that `prefix` contained the substring "/home/" on one
box but ""/Work/" on the other.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
basic bytecode to machine code compiler (part 3) Rouslan Korneychuk Python 2 06-21-2011 08:06 PM
basic bytecode to machine code compiler (part 2) Rouslan Korneychuk Python 0 05-18-2011 01:03 AM
a basic bytecode to machine code compiler Rouslan Korneychuk Python 10 04-03-2011 12:12 AM
does bytecode and machine code are same ? gk Java 13 09-22-2006 01:58 AM



Advertisments