By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,814 Members | 1,111 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,814 IT Pros & Developers. It's quick & easy.

Is bytecode machine (in)dependent?

P: n/a
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,

Oct 28 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
[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.
Oct 28 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.