Executing bytecode from a string.

Peter Otten __peter__ at web.de
Wed Aug 11 09:08:52 EDT 2004


Benjamin Scherrey wrote:

> I'm curious as to how difficult it would be to take a string that contains
> compiled bytecode, load it into memory, give it a function name then
> execute that function. I'm thinking of a database that contains compiled
> objects that I can load and execute. I'm also curious as to what level of
> grainularity this would work - module, class, class method, function?
> Anyone tried to do this before? Obviously dependencies are a consideration
> but I'm more interested in the mechanics of this. Appreciate ideas &
> pointers you might have...
> 
> Ben Scherrey

The following was written just for fun with no pretension that it will work
in the "real world". I've only manipulated co_consts and co_code of my
custom code object - you can investigate the other parameters one after
another and replace them with something at your choice.
The question that remains - how do you want to create the bytecode strings?
If from actual functions, why not store their source code, if from
codeobjects, why not marshal.dump()/load() them?

Peter

<code>
# get hold of the function and code types
def f(): pass
function = type(f)
del f
code = type(compile("def f(): pass", "noname", "exec"))

template = compile("def f(): pass", "noname", "exec")

def makeFunc(bytecode, consts):
    """ create a new function from a bytecode string and a consts tuple """

    # instead of inventing all code-attributes ourselves
    # copy those we are not interested in from an existing template
    co = template
    codeobj = code(co.co_argcount, co.co_nlocals, co.co_stacksize,
                    co.co_flags, bytecode, consts, co.co_names,
                    co.co_varnames, co.co_filename, co.co_name,
                    co.co_firstlineno, co.co_lnotab, co.co_freevars,
                    co.co_cellvars)

    return function(codeobj, globals(), "f", None, None)

# get hold of a valid bytecode string
# (I could have pasted the string literal from the interpreter,
# but I chose not to cheat :-)
def prototype():
    print "so what"
bytecode = prototype.func_code.co_code

# test what we have so far
g = makeFunc(bytecode, consts=(None, "it takes more than the byte-code",))
h = makeFunc(bytecode, consts=(None, "to make a function"))
g()
h()
</code>



More information about the Python-list mailing list