def test_load_classderef(self): concrete = ConcreteBytecode() concrete.cellvars = ['__class__'] concrete.freevars = ['__class__'] concrete.extend([ ConcreteInstr('LOAD_CLASSDEREF', 1), ConcreteInstr('STORE_DEREF', 1) ]) bytecode = concrete.to_bytecode() self.assertEqual(bytecode.freevars, ['__class__']) self.assertEqual(bytecode.cellvars, ['__class__']) self.assertEqual(list(bytecode), [ Instr('LOAD_CLASSDEREF', FreeVar('__class__'), lineno=1), Instr('STORE_DEREF', FreeVar('__class__'), lineno=1) ]) concrete = bytecode.to_concrete_bytecode() self.assertEqual(concrete.freevars, ['__class__']) self.assertEqual(concrete.cellvars, ['__class__']) self.assertEqual(list(concrete), [ ConcreteInstr('LOAD_CLASSDEREF', 1, lineno=1), ConcreteInstr('STORE_DEREF', 1, lineno=1) ]) code = concrete.to_code() self.assertEqual(code.co_freevars, ('__class__', )) self.assertEqual(code.co_cellvars, ('__class__', )) self.assertEqual( code.co_code, b'\x94\x01\x89\x01' if WORDCODE else b'\x94\x01\x00\x89\x01\x00')
def test_get_jump_target(self): jump_abs = ConcreteInstr("JUMP_ABSOLUTE", 3) self.assertEqual(jump_abs.get_jump_target(100), 3) jump_forward = ConcreteInstr("JUMP_FORWARD", 5) self.assertEqual(jump_forward.get_jump_target(10), 16 if OFFSET_AS_INSTRUCTION else 17)
def test_cellvar_freevar(self): concrete = ConcreteBytecode() concrete.cellvars = ["cell"] concrete.freevars = ["free"] concrete.append(ConcreteInstr("LOAD_DEREF", 0)) concrete.append(ConcreteInstr("LOAD_DEREF", 1)) code = concrete.to_code() concrete = ConcreteBytecode.from_code(code) self.assertEqual(concrete.cellvars, ["cell"]) self.assertEqual(concrete.freevars, ["free"]) self.assertEqual( list(concrete), [ ConcreteInstr("LOAD_DEREF", 0, lineno=1), ConcreteInstr("LOAD_DEREF", 1, lineno=1), ], ) bytecode = concrete.to_bytecode() self.assertEqual(bytecode.cellvars, ["cell"]) self.assertEqual( list(bytecode), [ Instr("LOAD_DEREF", CellVar("cell"), lineno=1), Instr("LOAD_DEREF", FreeVar("free"), lineno=1), ], )
def test_async_gen_no_flag_is_async_None(self): # Test inference in the absence of any flag set on the bytecode # Infer generator code = ConcreteBytecode() code.append(ConcreteInstr("YIELD_VALUE")) code.update_flags() self.assertTrue(bool(code.flags & CompilerFlags.GENERATOR)) # Infer coroutine code = ConcreteBytecode() code.append(ConcreteInstr("GET_AWAITABLE")) code.update_flags() self.assertTrue(bool(code.flags & CompilerFlags.COROUTINE)) # Infer coroutine or async generator for i, expected in ( ("YIELD_VALUE", CompilerFlags.ASYNC_GENERATOR), ("YIELD_FROM", CompilerFlags.COROUTINE), ): code = ConcreteBytecode() code.append(ConcreteInstr("GET_AWAITABLE")) code.append(ConcreteInstr(i)) code.update_flags() self.assertTrue(bool(code.flags & expected))
def test_async_gen_flags(self): # Test inference in the presence of pre-existing flags for is_async in (None, True): # Infer generator code = ConcreteBytecode() code.append(ConcreteInstr("YIELD_VALUE")) for f, expected in ( (CompilerFlags.COROUTINE, CompilerFlags.ASYNC_GENERATOR), (CompilerFlags.ASYNC_GENERATOR, CompilerFlags.ASYNC_GENERATOR), (CompilerFlags.ITERABLE_COROUTINE, CompilerFlags.ITERABLE_COROUTINE), ): code.flags = CompilerFlags(f) code.update_flags(is_async=is_async) self.assertTrue(bool(code.flags & expected)) # Infer coroutine code = ConcreteBytecode() code.append(ConcreteInstr("YIELD_FROM")) for f, expected in ( (CompilerFlags.COROUTINE, CompilerFlags.COROUTINE), (CompilerFlags.ASYNC_GENERATOR, CompilerFlags.COROUTINE), (CompilerFlags.ITERABLE_COROUTINE, CompilerFlags.ITERABLE_COROUTINE), ): code.flags = CompilerFlags(f) code.update_flags(is_async=is_async) self.assertTrue(bool(code.flags & expected)) # Crash on ITERABLE_COROUTINE with async bytecode code = ConcreteBytecode() code.append(ConcreteInstr("GET_AWAITABLE")) code.flags = CompilerFlags(CompilerFlags.ITERABLE_COROUTINE) with self.assertRaises(ValueError): code.update_flags(is_async=is_async)
def test_extended_lnotab(self): # x = 7 # y = 8 concrete = ConcreteBytecode([ ConcreteInstr("LOAD_CONST", 0), SetLineno(1 + 128), ConcreteInstr("STORE_NAME", 0), # line number goes backward! SetLineno(1 + 129), ConcreteInstr("LOAD_CONST", 1), SetLineno(1), ConcreteInstr("STORE_NAME", 1), ]) concrete.consts = [7, 8] concrete.names = ["x", "y"] concrete.first_lineno = 1 if sys.version_info >= (3, 6): code = concrete.to_code() expected = b"d\x00Z\x00d\x01Z\x01" self.assertEqual(code.co_code, expected) self.assertEqual(code.co_firstlineno, 1) self.assertEqual(code.co_lnotab, b"\x00\x7f\x02\x01\x02\x01\x00\x80\x02\xff") else: with self.assertRaises(ValueError) as cm: code = concrete.to_code() self.assertEqual( str(cm.exception), "negative line number delta is not supported " "on Python < 3.6", )
def test_negative_lnotab(self): # x = 7 # y = 8 concrete = ConcreteBytecode([ ConcreteInstr("LOAD_CONST", 0), ConcreteInstr("STORE_NAME", 0), # line number goes backward! SetLineno(2), ConcreteInstr("LOAD_CONST", 1), ConcreteInstr("STORE_NAME", 1) ]) concrete.consts = [7, 8] concrete.names = ['x', 'y'] concrete.first_lineno = 5 if sys.version_info >= (3, 6): code = concrete.to_code() expected = b'd\x00Z\x00d\x01Z\x01' self.assertEqual(code.co_code, expected) self.assertEqual(code.co_firstlineno, 5) self.assertEqual(code.co_lnotab, b'\x04\xfd') else: with self.assertRaises(ValueError) as cm: code = concrete.to_code() self.assertEqual(str(cm.exception), "negative line number delta is not supported " "on Python < 3.6")
def test_get_jump_target(self): jump_abs = ConcreteInstr("JUMP_ABSOLUTE", 3) self.assertEqual(jump_abs.get_jump_target(100), 3) jump_forward = ConcreteInstr("JUMP_FORWARD", 5) self.assertEqual(jump_forward.get_jump_target(10), 17 if WORDCODE else 18)
def test_assemble(self): instr = ConcreteInstr("NOP") self.assertEqual(instr.assemble(), b'\t') instr = ConcreteInstr("LOAD_CONST", 3) self.assertEqual(instr.assemble(), b'd\x03\x00') instr = ConcreteInstr("LOAD_CONST", 0x1234abcd) self.assertEqual(instr.assemble(), b'\x904\x12d\xcd\xab')
def test_label2(self): bytecode = Bytecode() label = Label() bytecode.extend( [ Instr("LOAD_NAME", "test", lineno=1), Instr("POP_JUMP_IF_FALSE", label), Instr("LOAD_CONST", 5, lineno=2), Instr("STORE_NAME", "x"), Instr("JUMP_FORWARD", label), Instr("LOAD_CONST", 7, lineno=4), Instr("STORE_NAME", "x"), label, Instr("LOAD_CONST", None), Instr("RETURN_VALUE"), ] ) concrete = bytecode.to_concrete_bytecode() expected = [ ConcreteInstr("LOAD_NAME", 0, lineno=1), ConcreteInstr("POP_JUMP_IF_FALSE", 14, lineno=1), ConcreteInstr("LOAD_CONST", 0, lineno=2), ConcreteInstr("STORE_NAME", 1, lineno=2), ConcreteInstr("JUMP_FORWARD", 4, lineno=2), ConcreteInstr("LOAD_CONST", 1, lineno=4), ConcreteInstr("STORE_NAME", 1, lineno=4), ConcreteInstr("LOAD_CONST", 2, lineno=4), ConcreteInstr("RETURN_VALUE", lineno=4), ] self.assertListEqual(list(concrete), expected) self.assertListEqual(concrete.consts, [5, 7, None]) self.assertListEqual(concrete.names, ["test", "x"]) self.assertListEqual(concrete.varnames, [])
def test_constructor(self): with self.assertRaises(ValueError): # need an argument ConcreteInstr("LOAD_CONST") with self.assertRaises(ValueError): # must not have an argument ConcreteInstr("ROT_TWO", 33) # invalid argument with self.assertRaises(TypeError): ConcreteInstr("LOAD_CONST", 1.0) with self.assertRaises(ValueError): ConcreteInstr("LOAD_CONST", -1) with self.assertRaises(TypeError): ConcreteInstr("LOAD_CONST", 5, lineno=1.0) with self.assertRaises(ValueError): ConcreteInstr("LOAD_CONST", 5, lineno=-1) # test maximum argument with self.assertRaises(ValueError): ConcreteInstr("LOAD_CONST", 2147483647 + 1) instr = ConcreteInstr("LOAD_CONST", 2147483647) self.assertEqual(instr.arg, 2147483647) # test meaningless extended args instr = ConcreteInstr("LOAD_FAST", 8, lineno=3, extended_args=1) self.assertEqual(instr.name, "LOAD_FAST") self.assertEqual(instr.arg, 8) self.assertEqual(instr.lineno, 3) self.assertEqual(instr.size, 4)
def test_label2(self): bytecode = Bytecode() label = Label() bytecode.extend([ Instr('LOAD_NAME', 'test', lineno=1), Instr('POP_JUMP_IF_FALSE', label), Instr('LOAD_CONST', 5, lineno=2), Instr('STORE_NAME', 'x'), Instr('JUMP_FORWARD', label), Instr('LOAD_CONST', 7, lineno=4), Instr('STORE_NAME', 'x'), label, Instr('LOAD_CONST', None), Instr('RETURN_VALUE') ]) concrete = bytecode.to_concrete_bytecode() expected = [ ConcreteInstr('LOAD_NAME', 0, lineno=1), ConcreteInstr('POP_JUMP_IF_FALSE', 14 if WORDCODE else 21, lineno=1), ConcreteInstr('LOAD_CONST', 0, lineno=2), ConcreteInstr('STORE_NAME', 1, lineno=2), ConcreteInstr('JUMP_FORWARD', 4 if WORDCODE else 6, lineno=2), ConcreteInstr('LOAD_CONST', 1, lineno=4), ConcreteInstr('STORE_NAME', 1, lineno=4), ConcreteInstr('LOAD_CONST', 2, lineno=4), ConcreteInstr('RETURN_VALUE', lineno=4) ] self.assertListEqual(list(concrete), expected) self.assertListEqual(concrete.consts, [5, 7, None]) self.assertListEqual(concrete.names, ['test', 'x']) self.assertListEqual(concrete.varnames, [])
def test_flag_inference(self): # Check no loss of non-infered flags code = ControlFlowGraph() code.flags |= (CompilerFlags.NEWLOCALS | CompilerFlags.VARARGS | CompilerFlags.VARKEYWORDS | CompilerFlags.NESTED | CompilerFlags.FUTURE_GENERATOR_STOP) code.update_flags() for f in (CompilerFlags.NEWLOCALS, CompilerFlags.VARARGS, CompilerFlags.VARKEYWORDS, CompilerFlags.NESTED, CompilerFlags.NOFREE, CompilerFlags.OPTIMIZED, CompilerFlags.FUTURE_GENERATOR_STOP): self.assertTrue(bool(code.flags & f)) # Infer optimized and nofree code = Bytecode() flags = infer_flags(code) self.assertTrue(bool(flags & CompilerFlags.OPTIMIZED)) self.assertTrue(bool(flags & CompilerFlags.NOFREE)) code.append(ConcreteInstr('STORE_NAME', 1)) flags = infer_flags(code) self.assertFalse(bool(flags & CompilerFlags.OPTIMIZED)) self.assertTrue(bool(flags & CompilerFlags.NOFREE)) code.append(ConcreteInstr('STORE_DEREF', 2)) code.update_flags() self.assertFalse(bool(code.flags & CompilerFlags.OPTIMIZED)) self.assertFalse(bool(code.flags & CompilerFlags.NOFREE)) # Infer generator code = ConcreteBytecode() code.append(ConcreteInstr('YIELD_VALUE')) for is_async, expected in ((False, CompilerFlags.GENERATOR), (True, CompilerFlags.ASYNC_GENERATOR)): self.assertTrue(bool(infer_flags(code, is_async) & expected)) # Infer coroutine code = ConcreteBytecode() code.append(ConcreteInstr('GET_AWAITABLE')) iter_flags = CompilerFlags(CompilerFlags.ITERABLE_COROUTINE) for f, expected in ((CompilerFlags(0), True), (iter_flags, False)): code.flags = f self.assertEqual(bool(infer_flags(code) & CompilerFlags.COROUTINE), expected) # Test check flag sanity code.append(ConcreteInstr('YIELD_VALUE')) code.flags = CompilerFlags(CompilerFlags.GENERATOR | CompilerFlags.COROUTINE) infer_flags(code, is_async=True) # Just want to be sure it pases with self.assertRaises(ValueError): code.update_flags() with self.assertRaises(ValueError): infer_flags(None)
def test_disassemble(self): instr = ConcreteInstr.disassemble(1, b'\td\x03\x00', 0) self.assertEqual(instr, ConcreteInstr("NOP", lineno=1)) instr = ConcreteInstr.disassemble(2, b'\td\x03\x00', 1) self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2)) code = b'\x904\x12d\xcd\xab' instr = ConcreteInstr.disassemble(3, code, 0) self.assertEqual(instr, ConcreteInstr('EXTENDED_ARG', 0x1234, lineno=3))
def test_cellvars(self): code = Bytecode() code.cellvars = ['x'] code.freevars = ['y'] code.extend([Instr('LOAD_DEREF', CellVar('x'), lineno=1), Instr('LOAD_DEREF', FreeVar('y'), lineno=1)]) concrete = code.to_concrete_bytecode() self.assertEqual(concrete.cellvars, ['x']) self.assertEqual(concrete.freevars, ['y']) code.extend([ConcreteInstr("LOAD_DEREF", 0, lineno=1), ConcreteInstr("LOAD_DEREF", 1, lineno=1)])
def test_disassemble(self): code = b"\t\x00d\x03" instr = ConcreteInstr.disassemble(1, code, 0) self.assertEqual(instr, ConcreteInstr("NOP", lineno=1)) instr = ConcreteInstr.disassemble(2, code, 2) self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2)) code = b"\x90\x12\x904\x90\xabd\xcd" instr = ConcreteInstr.disassemble(3, code, 0) self.assertEqual(instr, ConcreteInstr("EXTENDED_ARG", 0x12, lineno=3))
def test_disassemble(self): code = b'\t\x00d\x03' if WORDCODE else b'\td\x03\x00' instr = ConcreteInstr.disassemble(1, code, 0) self.assertEqual(instr, ConcreteInstr("NOP", lineno=1)) instr = ConcreteInstr.disassemble(2, code, 2 if WORDCODE else 1) self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2)) code = b'\x90\x12\x904\x90\xabd\xcd' if WORDCODE else b'\x904\x12d\xcd\xab' instr = ConcreteInstr.disassemble(3, code, 0) self.assertEqual(instr, ConcreteInstr('EXTENDED_ARG', 0x12 if WORDCODE else 0x1234, lineno=3))
def test_attr(self): code_obj = get_code("x = 5") code = ConcreteBytecode.from_code(code_obj) self.assertEqual(code.consts, [5, None]) self.assertEqual(code.names, ['x']) self.assertEqual(code.varnames, []) self.assertEqual(code.freevars, []) self.assertListEqual(list(code), [ConcreteInstr('LOAD_CONST', 0, lineno=1), ConcreteInstr('STORE_NAME', 0, lineno=1), ConcreteInstr('LOAD_CONST', 1, lineno=1), ConcreteInstr('RETURN_VALUE', lineno=1)])
def test_disassemble(self): code = b"\td\x03\x00" instr = ConcreteInstr.disassemble(1, code, 0) self.assertEqual(instr, ConcreteInstr("NOP", lineno=1)) instr = ConcreteInstr.disassemble(2, code, 1) self.assertEqual(instr, ConcreteInstr("LOAD_CONST", 3, lineno=2)) code = b"%c4\x12d\xcd\xab" % EXTENDED_ARG instr = ConcreteInstr.disassemble(3, code, 0) self.assertEqual(instr, ConcreteInstr("EXTENDED_ARG", 0x1234, lineno=3))
def test_to_code_lnotab(self): # We use an actual function for the simple case to # ensure we get lnotab right def f(): # # x = 7 # noqa y = 8 # noqa z = 9 # noqa fl = f.__code__.co_firstlineno concrete = ConcreteBytecode() concrete.consts = [None, 7, 8, 9] concrete.varnames = ["x", "y", "z"] concrete.first_lineno = fl concrete.extend([ SetLineno(fl + 3), ConcreteInstr("LOAD_CONST", 1), ConcreteInstr("STORE_FAST", 0), SetLineno(fl + 4), ConcreteInstr("LOAD_CONST", 2), ConcreteInstr("STORE_FAST", 1), SetLineno(fl + 5), ConcreteInstr("LOAD_CONST", 3), ConcreteInstr("STORE_FAST", 2), ConcreteInstr("LOAD_CONST", 0), ConcreteInstr("RETURN_VALUE"), ]) code = concrete.to_code() self.assertEqual(code.co_code, f.__code__.co_code) self.assertEqual(code.co_lnotab, f.__code__.co_lnotab) if sys.version_info >= (3, 10): self.assertEqual(code.co_linetable, f.__code__.co_linetable)
def test_freevar(self): concrete = ConcreteBytecode() concrete.freevars = ["x"] concrete.append(ConcreteInstr("LOAD_DEREF", 0)) code = concrete.to_code() concrete = ConcreteBytecode.from_code(code) self.assertEqual(concrete.cellvars, []) self.assertEqual(concrete.freevars, ["x"]) self.assertEqual(list(concrete), [ConcreteInstr("LOAD_DEREF", 0, lineno=1)]) bytecode = concrete.to_bytecode() self.assertEqual(bytecode.cellvars, []) self.assertEqual(list(bytecode), [Instr("LOAD_DEREF", FreeVar("x"), lineno=1)])
def test_label(self): code = Bytecode() label = Label() code.extend([Instr('LOAD_CONST', 'hello', lineno=1), Instr('JUMP_FORWARD', label, lineno=1), label, Instr('POP_TOP', lineno=1)]) code = code.to_concrete_bytecode() expected = [ConcreteInstr('LOAD_CONST', 0, lineno=1), ConcreteInstr('JUMP_FORWARD', 0, lineno=1), ConcreteInstr('POP_TOP', lineno=1)] self.assertListEqual(list(code), expected) self.assertListEqual(code.consts, ['hello'])
def test_cellvars(self): code = Bytecode() code.cellvars = ["x"] code.freevars = ["y"] code.extend([ Instr("LOAD_DEREF", CellVar("x"), lineno=1), Instr("LOAD_DEREF", FreeVar("y"), lineno=1), ]) concrete = code.to_concrete_bytecode() self.assertEqual(concrete.cellvars, ["x"]) self.assertEqual(concrete.freevars, ["y"]) code.extend([ ConcreteInstr("LOAD_DEREF", 0, lineno=1), ConcreteInstr("LOAD_DEREF", 1, lineno=1), ])
def test_dont_merge_constants(self): # test two constants which are equal but have a different type code = Bytecode() code.extend([Instr('LOAD_CONST', 5, lineno=1), Instr('LOAD_CONST', 5.0, lineno=1), Instr('LOAD_CONST', -0.0, lineno=1), Instr('LOAD_CONST', +0.0, lineno=1)]) code = code.to_concrete_bytecode() expected = [ConcreteInstr('LOAD_CONST', 0, lineno=1), ConcreteInstr('LOAD_CONST', 1, lineno=1), ConcreteInstr('LOAD_CONST', 2, lineno=1), ConcreteInstr('LOAD_CONST', 3, lineno=1)] self.assertListEqual(list(code), expected) self.assertListEqual(code.consts, [5, 5.0, -0.0, +0.0])
def test_attr(self): instr = ConcreteInstr("LOAD_CONST", 5, lineno=12) self.assertEqual(instr.name, "LOAD_CONST") self.assertEqual(instr.opcode, 100) self.assertEqual(instr.arg, 5) self.assertEqual(instr.lineno, 12) self.assertEqual(instr.size, 2)
def test_async_gen_no_flag_is_async_False(self): # Test inference when we request a non-async function # Infer generator code = ConcreteBytecode() code.append(ConcreteInstr("YIELD_VALUE")) code.flags = CompilerFlags(CompilerFlags.COROUTINE) code.update_flags(is_async=False) self.assertTrue(bool(code.flags & CompilerFlags.GENERATOR)) # Abort on coroutine code = ConcreteBytecode() code.append(ConcreteInstr("GET_AWAITABLE")) code.flags = CompilerFlags(CompilerFlags.COROUTINE) with self.assertRaises(ValueError): code.update_flags(is_async=False)
def test_attr(self): code_obj = get_code("x = 5") code = ConcreteBytecode.from_code(code_obj) self.assertEqual(code.consts, [5, None]) self.assertEqual(code.names, ["x"]) self.assertEqual(code.varnames, []) self.assertEqual(code.freevars, []) self.assertListEqual( list(code), [ ConcreteInstr("LOAD_CONST", 0, lineno=1), ConcreteInstr("STORE_NAME", 0, lineno=1), ConcreteInstr("LOAD_CONST", 1, lineno=1), ConcreteInstr("RETURN_VALUE", lineno=1), ], )
def test_eq(self): code = ConcreteBytecode() self.assertFalse(code == 1) for name, val in ( ("names", ["a"]), ("varnames", ["a"]), ("consts", [1]), ("argcount", 1), ("kwonlyargcount", 2), ("flags", CompilerFlags(CompilerFlags.GENERATOR)), ("first_lineno", 10), ("filename", "xxxx.py"), ("name", "__x"), ("docstring", "x-x-x"), ("cellvars", [CellVar("x")]), ("freevars", [FreeVar("x")]), ): c = ConcreteBytecode() setattr(c, name, val) # For obscure reasons using assertNotEqual here fail self.assertFalse(code == c) if sys.version_info > (3, 8): c = ConcreteBytecode() c.posonlyargcount = 10 self.assertFalse(code == c) c = ConcreteBytecode() c.consts = [1] code.consts = [1] c.append(ConcreteInstr("LOAD_CONST", 0)) self.assertFalse(code == c)
def test_cellvar(self): concrete = ConcreteBytecode() concrete.cellvars = ['x'] concrete.append(ConcreteInstr('LOAD_DEREF', 0)) code = concrete.to_code() concrete = ConcreteBytecode.from_code(code) self.assertEqual(concrete.cellvars, ['x']) self.assertEqual(concrete.freevars, []) self.assertEqual(list(concrete), [ConcreteInstr('LOAD_DEREF', 0, lineno=1)]) bytecode = concrete.to_bytecode() self.assertEqual(bytecode.cellvars, ['x']) self.assertEqual(list(bytecode), [Instr('LOAD_DEREF', CellVar('x'), lineno=1)])
def test_assemble(self): instr = ConcreteInstr("NOP") self.assertEqual(instr.assemble(), b'\t\x00' if WORDCODE else b'\t') instr = ConcreteInstr("LOAD_CONST", 3) self.assertEqual(instr.assemble(), b'd\x03' if WORDCODE else b'd\x03\x00') instr = ConcreteInstr("LOAD_CONST", 0x1234abcd) self.assertEqual(instr.assemble(), (b'\x90\x12\x904\x90\xabd\xcd' if WORDCODE else b'\x904\x12d\xcd\xab')) instr = ConcreteInstr("LOAD_CONST", 3, extended_args=1) self.assertEqual( instr.assemble(), (b'\x90\x00d\x03' if WORDCODE else b'\x90\x00\x00d\x03\x00'))