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>