SlideShare une entreprise Scribd logo
1  sur  51
Télécharger pour lire hors ligne
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
} /*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

Contenu connexe

Tendances

Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
Abed Bukhari
 

Tendances (20)

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

Similaire à Bytes in the Machine: Inside the CPython interpreter

«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
it-people
 

Similaire à Bytes in the Machine: Inside the CPython interpreter (20)

JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Boosting Developer Productivity with Clang
Boosting Developer Productivity with ClangBoosting Developer Productivity with Clang
Boosting Developer Productivity with Clang
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
 
Building a DSL with GraalVM (CodeOne)
Building a DSL with GraalVM (CodeOne)Building a DSL with GraalVM (CodeOne)
Building a DSL with GraalVM (CodeOne)
 
2.1 ### uVision Project, (C) Keil Software .docx
2.1   ### uVision Project, (C) Keil Software    .docx2.1   ### uVision Project, (C) Keil Software    .docx
2.1 ### uVision Project, (C) Keil Software .docx
 
Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)
 
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
 
Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015
 
Davide Berardi - Linux hardening and security measures against Memory corruption
Davide Berardi - Linux hardening and security measures against Memory corruptionDavide Berardi - Linux hardening and security measures against Memory corruption
Davide Berardi - Linux hardening and security measures against Memory corruption
 
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
ITGM #9 - Коварный CodeType, или от segfault'а к работающему кодуITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
 
PythonBrasil[8] - CPython for dummies
PythonBrasil[8] - CPython for dummiesPythonBrasil[8] - CPython for dummies
PythonBrasil[8] - CPython for dummies
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
GCC
GCCGCC
GCC
 
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
PVS-Studio 5.00, a solution for developers of modern resource-intensive appl...
 
C++ amp on linux
C++ amp on linuxC++ amp on linux
C++ amp on linux
 
OpenMP
OpenMPOpenMP
OpenMP
 
Cpp tutorial
Cpp tutorialCpp tutorial
Cpp tutorial
 
PyCon KR 2019 sprint - RustPython by example
PyCon KR 2019 sprint  - RustPython by examplePyCon KR 2019 sprint  - RustPython by example
PyCon KR 2019 sprint - RustPython by example
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Dernier (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

Bytes in the Machine: Inside the CPython interpreter