Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def create_bytecode(self, source, function=False):
code = self.compile(source, function=function)
bytecode = Bytecode.from_code(code)
from bytecode.tests import dump_code
dump_code(bytecode, lineno=False)
#dump_code(bytecode)
bytecode = bytecode.to_bytecode_blocks()
if not function:
block = bytecode[-1]
if not(block[-2].name == "LOAD_CONST"
and block[-2].arg is None
and block[-1].name == "RETURN_VALUE"):
raise ValueError("unable to find implicit RETURN_VALUE : %s"
% block[-2:])
del block[-2:]
return bytecode
def test_disassemble(self):
code = get_code("""
if test:
x = 1
else:
x = 2
""")
bytecode = Bytecode.from_code(code)
label_else = Label()
label_exit = Label()
self.assertEqual(bytecode,
[Instr(1, 'LOAD_NAME', 'test'),
Instr(1, 'POP_JUMP_IF_FALSE', label_else),
Instr(2, 'LOAD_CONST', 1),
Instr(2, 'STORE_NAME', 'x'),
Instr(2, 'JUMP_FORWARD', label_exit),
label_else,
Instr(4, 'LOAD_CONST', 2),
Instr(4, 'STORE_NAME', 'x'),
label_exit,
Instr(4, 'LOAD_CONST', None),
Instr(4, 'RETURN_VALUE')])
def insert_python_expr(self, pydata, trim=True):
""" Insert the compiled code for a Python Expression ast or string.
"""
code = compile(pydata, self.filename, mode='eval')
bc_code = bc.Bytecode.from_code(code)
if trim: # skip ReturnValue
bc_code = bc_code[:-1]
self.code_ops.extend(bc_code)
def optimize(self, code_obj):
bytecode = Bytecode.from_code(code_obj)
cfg = ControlFlowGraph.from_bytecode(bytecode)
self._optimize(cfg)
bytecode = cfg.to_bytecode()
code = bytecode.to_code()
return code
Parameters
----------
code : CodeType
The code object created by the Enaml compiler.
f_globals : dict
The global scope for the returned function.
Returns
-------
result : FunctionType
A new function with optimized local variable access
and instrumentation for inverting the operation.
"""
bc_code = bc.Bytecode.from_code(code)
optimize_locals(bc_code)
bc_code = inject_inversion(bc_code)
bc_code.flags ^= (bc_code.flags & bc.CompilerFlags.NEWLOCALS)
bc_code.argnames = ['_[inverter]', '_[value]'] + bc_code.argnames
bc_code.argcount += 2
new_code = bc_code.to_code()
return FunctionType(new_code, f_globals)
"""
# Code generator used to modify the bytecode
cg = CodeGenerator()
fetch_helpers(cg)
# Scan all ops to detect function call after GET_ITER
for instr in code:
if not isinstance(instr, bc.Instr):
cg.code_ops.append(instr)
continue
i_name, i_arg = instr.name, instr.arg
if isinstance(i_arg, CodeType):
# Allow to pass the dynamic scope as locals. There is no need
# to copy it as internal variables are stored in fast locals
# and hence does not affect the scope content.
inner = bc.Bytecode.from_code(i_arg)
inner.flags ^= (inner.flags & bc.CompilerFlags.NEWLOCALS)
# Set the NESTED flag since even though we may have obtained the
# outer code from an expr it will run as a function.
inner.flags |= bc.CompilerFlags.NESTED
run_in_dynamic_scope(inner, global_vars)
inner.update_flags()
i_arg = inner.to_code()
elif any(i_name == make_fun_op for make_fun_op in _MAKE_FUNC):
cg.code_ops.append(bc.Instr(i_name, i_arg)) # func
load_helper(cg, 'wrap_func') # func -> wrap
cg.rot_two() # wrap -> func
cg.load_global('__scope__') # wrap -> func -> scope
cg.call_function(2) # wrapped
continue
cg.code_ops.append(bc.Instr(i_name, i_arg))
The enaml ast node of interest.
index : int
The index of the target node in the node list.
name : str
The attribute name to be bound.
"""
mode = COMPILE_MODE[type(node.value)]
global_vars, has_defs = analyse_globals_and_func_defs(node.value.ast)
# In mode exec, the body of the operator has been wrapped in a function def
# after the compilation we extract the function code
if mode == 'exec':
code = compile(node.value.ast, cg.filename, mode=mode)
for instr in bc.Bytecode.from_code(code):
i_arg = instr.arg
if isinstance(i_arg, CodeType):
code = i_arg
break
else:
code = compile(node.value.ast, cg.filename, mode=mode)
b_code = bc.Bytecode.from_code(code)
if has_defs:
run_in_dynamic_scope(b_code, global_vars)
else:
rewrite_globals_access(b_code, global_vars)
code = b_code.to_code()
with cg.try_squash_raise():
cg.set_lineno(node.lineno)
def func_info(cls, func: types.FunctionType) -> types.FunctionType:
names = func.__code__.co_names
code = Bytecode.from_code(func.__code__)
codeinfo = cls.code_info(code)
def r_compile():
jit_func = jit_compile_to_cython(self)
print("jit_func", type(jit_func))
bc = Bytecode()
bc.append(PyInstr(InstrNames.LOAD_CONST, jit_func))
bc.extend(
[load_arg(each, cellvars, lineno) for each in argnames])
bc.extend([
PyInstr(InstrNames.CALL_FUNCTION, len(argnames)),
PyInstr(InstrNames.RETURN_VALUE)
])
bc._copy_attr_from(code)
start_func.__code__ = bc.to_code()
def __init__(self, module, block, module_name, extra):
self.module = module
self.block = block
self.module_name = module_name
self._extra = extra
self._id = uuid4()
self.name = self.block[1].arg
self.start_line_no = self.block[0].lineno
self.code_object = self.block[0].arg
# dis.dis(code_object)
self.code, self.dictionary_defs = preprocess_method_body(self.code_object)
self.bytecode = Bytecode.from_code(self.code)
self.setup()