SlideShare a Scribd company logo
Byterun:
A (C)Python interpreter in
Python
Allison Kaptur
github.com/akaptur
akaptur.com
@akaptur
Byterun
with Ned Batchelder
Based on
# pyvm2 by Paul Swartz (z3p)
from http://www.twistedmatrix.com/users/
z3p/
“Interpreter”
1. Lexing
2. Parsing
3. Compiling
4. Interpreting
The Python virtual machine:
A bytecode interpreter
Bytecode:
the internal representation
of a python program in the
interpreter
Why write an interpreter?
>>> if a or b:
... pass
Testing
def test_for_loop(self):
self.assert_ok("""
out = ""
for i in range(5):
out = out + str(i)
print(out)
""")
A problem
def test_for_loop(self):
self.assert_ok("""
g = (x*x for x in range(5))
h = (y+1 for y in g)
print(list(h))
""")
A simple VM
- LOAD_VALUE
- ADD_TWO_VALUES
- PRINT_ANSWER
A simple VM
"7 + 5"
["LOAD_VALUE",
"LOAD_VALUE",
"ADD_TWO_VALUES",
"PRINT_ANSWER"]
7
5
12
Before
After
ADD_TWO_
VALUES
After
LOAD_
VALUE
A simple VM
After
PRINT_
ANSWER
A simple VM
what_to_execute = {
"instructions":
[("LOAD_VALUE", 0),
("LOAD_VALUE", 1),
("ADD_TWO_VALUES", None),
("PRINT_ANSWER", None)],
"numbers": [7, 5] }
class Interpreter(object):
def __init__(self):
self.stack = []
def value_loader(self, number):
self.stack.append(number)
def answer_printer(self):
answer = self.stack.pop()
print(answer)
def two_value_adder(self):
first_num = self.stack.pop()
second_num = self.stack.pop()
total = first_num + second_num
self.stack.append(total)
def run_code(self, what_to_execute):
instrs = what_to_execute["instructions"]
numbers = what_to_execute["numbers"]
for each_step in instrs:
instruction, argument = each_step
if instruction == "LOAD_VALUE":
number = numbers[argument]
self.value_loader(number)
elif instruction == "ADD_TWO_VALUES":
self.two_value_adder()
elif instruction == "PRINT_ANSWER":
self.answer_printer()
interpreter = Interpreter()
interpreter.run_code(what_to_execute)
# 12
Bytecode: it’s bytes!
>>> def mod(a, b):
... ans = a % b
... return ans
Bytecode: it’s bytes!
Function
Code
object
Bytecode
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod.func_code.co_code
Bytecode: it’s bytes!
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod.func_code.co_code
'|x00x00|
x01x00x16}x02x00|x02x00S'
Bytecode: it’s bytes!
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod.func_code.co_code
‘|x00x00|
x01x00x16}x02x00|x02x00S'
>>> [ord(b) for b in
mod.func_code.co_code]
[124, 0, 0, 124, 1, 0, 22, 125,
2, 0, 124, 2, 0, 83]
dis, a bytecode disassembler
>>> import dis
>>> dis.dis(mod)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
dis, a bytecode disassembler
>>> dis.dis(mod)
line ind name arg hint
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
Bytecode: it’s bytes!
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(7,5)
7
5
2
Before
After
BINARY_
MODULO
After
LOAD_
FAST
The Python interpreter
After
STORE_
FAST
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(7,5)
>>> dis.dis(mod)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
c data stack ->
a
l
l
s
t
a
c
k
Frame: main
Frame: mod
7 5
Frame: main
Frame: fact
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
3 3fact 1
Frame: main
Frame: fact
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
3 2fact
Frame: main
Frame: fact
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
3
Frame: fact 2
Frame: main
Frame: fact 3
Frame: fact 2
Frame: fact 1
Frame: main
Frame: fact 3
Frame: fact 2 1
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
Frame: main
Frame: fact 3 2
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
Frame: main
Frame: fact 6
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
Frame: main
Frame: fact
6
>>> def fact(n):
... if n < 2: return 1
... else: return n * fact(n-1)
>>> fact(3)
Python VM:
- A collection of frames
- Data stacks on frames
- A way to run frames
>>> import dis
>>> dis.dis(mod)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
Instructions we need
Bytes in the Machine: Inside the CPython interpreter
} /*switch*/
/* Main switch on opcode
*/
READ_TIMESTAMP(inst0);
switch (opcode) {
#ifdef CASE_TOO_BIG
default: switch (opcode) {
#endif
/* Turn this on if your compiler chokes on the big switch: */
/* #define CASE_TOO_BIG 1 */
Instructions we need
>>> import dis
>>> dis.dis(mod)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
case LOAD_FAST:
x = GETLOCAL(oparg);
if (x != NULL) {
Py_INCREF(x);
PUSH(x);
goto fast_next_opcode;
}
format_exc_check_arg(PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_varnames,
oparg));
break;
case BINARY_MODULO:
w = POP();
v = TOP();
if (PyString_CheckExact(v))
x = PyString_Format(v, w);
else
x = PyNumber_Remainder(v, w);
Py_DECREF(v);
Py_DECREF(w);
SET_TOP(x);
if (x != NULL) continue;
break;
Back to our problem
g = (x*x for x in range(5))
h = (y+1 for y in g)
print(list(h))
It’s “dynamic”
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(15, 4)
3
“Dynamic”
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(15, 4)
3
>>> mod(“%s%s”, (“Py”, “Con”))
“Dynamic”
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(15, 4)
3
>>> mod(“%s%s”, (“Py”, “Con”))
PyCon
“Dynamic”
>>> def mod(a, b):
... ans = a % b
... return ans
>>> mod(15, 4)
3
>>> mod(“%s%s”, (“Py”, “Con”))
PyCon
>>> print “%s%s” % (“Py”, “Con”)
PyCon
dis, a bytecode disassembler
>>> import dis
>>> dis.dis(mod)
2 0 LOAD_FAST 0 (a)
3 LOAD_FAST 1 (b)
6 BINARY_MODULO
7 STORE_FAST 2 (ans)
3 10 LOAD_FAST 2 (ans)
13 RETURN_VALUE
case BINARY_MODULO:
w = POP();
v = TOP();
if (PyString_CheckExact(v))
x = PyString_Format(v, w);
else
x = PyNumber_Remainder(v, w);
Py_DECREF(v);
Py_DECREF(w);
SET_TOP(x);
if (x != NULL) continue;
break;
>>> class Surprising(object):
… def __mod__(self, other):
… print “Surprise!”
>>> s = Surprising()
>>> t = Surprsing()
>>> s % t
Surprise!
“In the general absence of type
information, almost every
instruction must be treated as
INVOKE_ARBITRARY_METHOD.”
- Russell Power and Alex
Rubinsteyn, “How Fast Can We
Make Interpreted Python?”
More
Great blogs
http://tech.blog.aknin.name/category/my-
projects/pythons-innards/ by @aknin
http://eli.thegreenplace.net/ by Eli Bendersky
Contribute! Find bugs!
https://github.com/nedbat/byterun
Apply to the Recurse Center!
www.recurse.com/apply

More Related Content

PDF
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
PDF
Allison Kaptur: Bytes in the Machine: Inside the CPython interpreter, PyGotha...
PDF
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
PDF
Diving into byte code optimization in python
PDF
Python opcodes
PDF
Exploring slides
PDF
All I know about rsc.io/c2go
DOCX
Wap to implement bitwise operators
"A 1,500 line (!!) switch statement powers your Python!" - Allison Kaptur, !!...
Allison Kaptur: Bytes in the Machine: Inside the CPython interpreter, PyGotha...
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Diving into byte code optimization in python
Python opcodes
Exploring slides
All I know about rsc.io/c2go
Wap to implement bitwise operators

What's hot (20)

PDF
Implementing Software Machines in C and Go
PPTX
Load-time Hacking using LD_PRELOAD
PDF
Faster Python, FOSDEM
PDF
Go a crash course
PDF
Introducción a Elixir
PPT
Whats new in_csharp4
PDF
PDF
Python sqlite3
PDF
When RV Meets CEP (RV 2016 Tutorial)
PDF
Playing 44CON CTF for fun and profit
PDF
Implementing Software Machines in Go and C
PPT
Python легко и просто. Красиво решаем повседневные задачи
PDF
Metarhia KievJS 22-Feb-2018
PDF
Python sqlite3 - flask
PDF
Functional Programming inside OOP? It’s possible with Python
PPTX
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
PDF
Phil Bartie QGIS PLPython
PDF
Powered by Python - PyCon Germany 2016
Implementing Software Machines in C and Go
Load-time Hacking using LD_PRELOAD
Faster Python, FOSDEM
Go a crash course
Introducción a Elixir
Whats new in_csharp4
Python sqlite3
When RV Meets CEP (RV 2016 Tutorial)
Playing 44CON CTF for fun and profit
Implementing Software Machines in Go and C
Python легко и просто. Красиво решаем повседневные задачи
Metarhia KievJS 22-Feb-2018
Python sqlite3 - flask
Functional Programming inside OOP? It’s possible with Python
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
Phil Bartie QGIS PLPython
Powered by Python - PyCon Germany 2016
Ad

Similar to Bytes in the Machine: Inside the CPython interpreter (20)

PDF
Building Interpreters with PyPy
PPTX
An Introduction : Python
PPTX
PRESENTATION ON PYTHON.pptx
ODP
Pysmbc Python C Modules are Easy
PDF
Python for Scientific Computing
PPTX
PDF
Notes about moving from python to c++ py contw 2020
PDF
Cluj.py Meetup: Extending Python in C
PPT
python within 50 page .ppt
PDF
Python and Pytorch tutorial and walkthrough
PPT
C463_02_python.ppt
PPT
C463_02_python.ppt
PPTX
IoT-Week1-Day1-Lab.pptx
PPT
Python tutorialfeb152012
PDF
PyPy's approach to construct domain-specific language runtime
PDF
Free Python Notes PDF - Python Crash Course
PDF
Python to scala
PPTX
Chapter 2 Python Language Basics, IPython.pptx
PDF
Python revision tour i
PPTX
app4.pptx
Building Interpreters with PyPy
An Introduction : Python
PRESENTATION ON PYTHON.pptx
Pysmbc Python C Modules are Easy
Python for Scientific Computing
Notes about moving from python to c++ py contw 2020
Cluj.py Meetup: Extending Python in C
python within 50 page .ppt
Python and Pytorch tutorial and walkthrough
C463_02_python.ppt
C463_02_python.ppt
IoT-Week1-Day1-Lab.pptx
Python tutorialfeb152012
PyPy's approach to construct domain-specific language runtime
Free Python Notes PDF - Python Crash Course
Python to scala
Chapter 2 Python Language Basics, IPython.pptx
Python revision tour i
app4.pptx
Ad

Recently uploaded (20)

PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PPTX
Spectroscopy.pptx food analysis technology
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Electronic commerce courselecture one. Pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Empathic Computing: Creating Shared Understanding
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Getting Started with Data Integration: FME Form 101
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Big Data Technologies - Introduction.pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Encapsulation_ Review paper, used for researhc scholars
SOPHOS-XG Firewall Administrator PPT.pptx
Spectroscopy.pptx food analysis technology
Building Integrated photovoltaic BIPV_UPV.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
20250228 LYD VKU AI Blended-Learning.pptx
Electronic commerce courselecture one. Pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Machine learning based COVID-19 study performance prediction
Empathic Computing: Creating Shared Understanding
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Digital-Transformation-Roadmap-for-Companies.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
Per capita expenditure prediction using model stacking based on satellite ima...
MYSQL Presentation for SQL database connectivity
Getting Started with Data Integration: FME Form 101
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Unlocking AI with Model Context Protocol (MCP)
Big Data Technologies - Introduction.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
Encapsulation_ Review paper, used for researhc scholars

Bytes in the Machine: Inside the CPython interpreter