Update documentation folder and readme.

This commit is contained in:
Windel Bouwman committed 2019-07-06 11:42:19 +02:00
1 parent a099ba5f8e
commit c64a974bfd
21 files changed
+86 -1204

No files matched your search

+13 -81
View File
@@ -105,99 +105,31 @@ There also are some unit tests, you can run those with cargo:
$ cargo test --all
```
# Using another standard library
# Using a standard library
As of now the standard library is under construction.
As of now the standard library is under construction. You can
use a standard library by setting the RUSTPYTHONPATH environment
variable.
To do this, follow this method:
```shell
$ export RUSTPYTHONPATH=~/GIT/RustPython/Lib
$ cargo run -- -c 'import xdrlib'
```
You can play around
with other standard libraries for python. For example,
the [ouroboros library](https://github.com/pybee/ouroboros).
To do this, follow this method:
```shell
$ cd ~/GIT
$ git clone git@github.com:pybee/ouroboros.git
$ export RUSTPYTHONPATH=~/GIT/ouroboros/ouroboros
$ cd RustPython
$ cargo run -- -c 'import statistics'
```
# Compiling to WebAssembly
At this stage RustPython only has preliminary support for web assembly. The instructions here are intended for developers or those wishing to run a toy example.
## Setup
To get started, install [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) and `npm`. ([wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/whirlwind-tour/basic-usage.html) should be installed by `wasm-pack`. if not, install it yourself)
<!-- Using `rustup` add the compile target `wasm32-unknown-emscripten`. To do so you will need to have [rustup](https://rustup.rs/) installed.
```bash
rustup target add wasm32-unknown-emscripten
```
Next, install `emsdk`:
```bash
curl https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | tar -zxv
cd emsdk-portable/
./emsdk update
./emsdk install sdk-incoming-64bit
./emsdk activate sdk-incoming-64bit
``` -->
## Build
Move into the `wasm` directory. This directory contains a library crate for interop
with python to rust to js and back in `wasm/lib`, the demo website found at
https://rustpython.github.io/demo in `wasm/demo`, and an example of how to use
the crate as a library in one's own JS app in `wasm/example`.
```sh
cd wasm
```
Go to the demo directory. This is the best way of seeing the changes made to either
the library or the JS demo, as the `rustpython_wasm` module is set to the global
JS variable `rp` on the website.
```sh
cd demo
```
Now, start the webpack development server. It'll compile the crate and then
the demo app. This will likely take a long time, both the wasm-pack portion and
the webpack portion (from after it says "Your crate has been correctly compiled"),
so be patient.
```sh
npm run dev
```
You can now open the webpage on https://localhost:8080 and Python code in either
the text box or browser devtools with:
```js
rp.pyEval(
`
print(js_vars['a'] * 9)
`,
{
vars: {
a: 9
}
}
);
```
Alternatively, you can run `npm run build` to build the app once, without watching
for changes, or `npm run dist` to build the app in release mode, both for the
crate and webpack.
[See this doc](wasm/README.md)
# Code style
The code style used is the default [rustfmt](https://github.com/rust-lang/rustfmt) codestyle. Please format your code accordingly.
We also use [clippy](https://github.com/rust-lang/rust-clippy) to detect rust code issues.
# Community
-30
View File
@@ -1,30 +0,0 @@
Byterun
* Builtins are exposed to frame.f_builtins
* f_builtins is assigned during frame creation,
self.f_builtins = f_locals['__builtins__']
if hasattr(self.f_builtins, '__dict__'):
self.f_builtins = self.f_builtins.__dict__
* f_locals has a __`____builtins___` field which is directly the `__builtins__` module
Jaspy
* The `module()` function creates either a NativeModule or PythonModule
* The objects in the module are PyType.native
* The function call is abstracted as a `call` function, which handles different
* IMPORT_NAME depends on `__import__()` in builtins
TODO:
* Implement a new type NativeFunction
* Wrap a function pointer in NativeFunction
* Refactor the CALL_FUNCTION case so it can call both python function and native function
* During frame creation, force push a native function `print` into the namespace
* Modify LOAD_* so they can search for names in builtins
* Create a module type
* In VM initialization, load the builtins module into locals
* During frame creation, create a field that contains the builtins dict
-17
View File
@@ -1,17 +0,0 @@
https://wiki.python.org/moin/SimplePrograms
Simple HTTP Server
bottle.py
http://pypi-ranking.info/alltime
- simplejson
- pep8
- httplib2
- argparse
http://learning-python.com/books/lp4e-examples.html
https://docs.python.org/3/tutorial/introduction.html#numbers
http://doc.pypy.org/en/latest/getting-started-dev.html#running-pypy-s-unit-tests
CPython Regression suite
https://github.com/python/cpython/tree/master/Lib/test
-13
View File
@@ -1,13 +0,0 @@
Create a frame class
change the environment to locals
turn run into run_code -> run_frame
TEST
Create a function class
implement MAKE_FUNCTION
implement CALL_FUNCTION
implement RETURN_VALUE
TEST function
-13
View File
@@ -1,13 +0,0 @@
# TODO: other notes should be put into here
# getattr()
- Required by this opcode [LOAD_ATTR](https://docs.python.org/3/library/dis.html#opcode-LOAD_ATTR)
- The builtin function: https://docs.python.org/3/library/functions.html?highlight=getattr#getattr
-
# Memory management
- https://docs.python.org/3.6/c-api/memory.html
# Bootstraping
- http://doc.pypy.org/en/latest/coding-guide.html#our-runtime-interpreter-is-rpython
- http://www.aosabook.org/en/pypy.html
-5
View File
@@ -1,5 +0,0 @@
Python bytecode: https://docs.python.org/3.4/library/dis.html
Python VM in python: https://github.com/nedbat/byterun
Python VM in JS: https://github.com/koehlma/jaspy
http://www.skulpt.org/
-43
View File
@@ -1,43 +0,0 @@
# Sharing plan
## Topics
* Python architecture
* Compiler -> VM
* Flavors
* Cpython
* Pypy
* Byterun
* JSapy (?)
* Why Rust
* Security
* Learning
* Implementation plan
* VM first
* Compiler second
* Tools for study
* dis doc
* byterun doc
* bytrun code
* cpython source
---
* Python VM
* Stack machine
* Load add print
* dis
* Interpreter loop
* Python Types
* Control flow
* Jump
* If
* Loop
---
* Function call
* Frame
* Builtins
@@ -1,529 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Flavors (powered by MDSlides)</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>/* Color */
.remark-slide-container {
background-color: black;
}
.remark-slide-content {
background-color:#0d0d0d;
color:lightgrey;
background-size:cover;
background-position:0,0;
font-family: Arial,sans-serif;
}
a {
/* color:lime; */
color: #ff8100
}
.remark-inline-code {
background-color:#1B1B1B;
border-radius: 0.35rem;
}
/* Font size */
html {font-size:22px;}
.remark-slide-content h1 {
margin: 0;
font-size: 3.998rem;
}
.remark-slide-content h2 {font-size: 2.827rem;}
.remark-slide-content h3 {font-size: 1.999rem;}
.remark-slide-content h4 {font-size: 1.414rem;}
.remark-slide-content small, .font_small {font-size: 0.707rem;}
.remark-slide-content li,p{
font-size: 1.414rem;
line-height: 1.999rem;
margin:0px;
}
.remark-slide-content li,p,table {
font-size: 1.414rem;
line-height: 1.999rem;
border-spacing: 0.707rem;
}
.remark-slide-content table {
border-collapse: collapse;
}
.remark-slide-content table thead th{
border-bottom: solid;
text-align: left;
}
.remark-slide-content table td{
padding-right: 0.707rem;
}
.remark-slide-content .footnote {
line-height: 1.414rem;
}
.remark-code {
background-color: black;
font-size: 0.9998rem;
word-wrap:auto;
font-family: "courier new", monospace;
}
/* Images */
img { max-width:100%;
max-height:100%;
}
/* Custom page classes */
.bleed {
background-size:cover !important;
background-position:center !important;
}
/* Custom block/inline classes */
.footnote {
font-size: 0.707rem;
}
.red {
color:red;
}
.green {
color:green;
}
.halfwidth {
/* for images */
width: 49%;
display:inline-block;
}
.fullwidth {
/* for images */
width: 100%;
display:inline-block;
}
.column-2 {
display:inline-block;
width: 49.5%;
}
.float-right-half {
width: 50%;
float:right;
}
.text-bg h1 {
background-color: rgba(0,0,0,0.5);
}
</style>
<style>/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs default {
color: #f8f8f2;
background: #23241f;
font-family: "courier new", monospace;
}
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f !important;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2 !important;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2 !important;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff !important;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e !important;
}
.hljs-strong {
font-weight: bold !important;
}
.hljs-emphasis {
font-style: italic !important;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672 !important;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef !important;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2 !important;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74 !important;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e !important;
}
</style>
</head>
<body onload="var slideshow = remark.create();">
<textarea id="source">
class: center, middle
##Python Interpreter in Rust
#### 2017/8/6, COSCUP
#### Shing Lyu
???
top, middle, bottom
left, center, right
---
### About Me
* 呂行 Shing Lyu
* Mozilla engineer
* Servo team
![rust_and_servo](data:image/png;base64,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 truncated
---
### Python's architecture
* Interpreted
* Garbage Collected
* Compiler => bytecode => VM
![python](data:image/png;base64,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 truncated
---
background-image: url('pic/ice-cream.jpg')
class: center, middle, bleed, text-bg
# Flavors
---
### Python Flavors
* CPython (THE python)
* Jython (JVM)
* IronPython (.NET)
* Pypy
* Educational
* Byterun
* Jsapy (JS)
* Brython (Python in browser)
---
class: center, middle
# Why & How?
---
### Why rewriting Python in Rust?
* Memory safety (?)
* Learn about Python's internal
* Learn to write Rust from scratch
* FUN!
---
### Implementation strategy
* Mostly follow CPython 3.6
* Focus on the VM first, then the compiler
* Use the Python built-in compiler to generate bytecode
* Focus on learning rather than usability
---
### Milestones
* Basic arithmetics
* Variables
* Control flows (require JUMP)
* Function call (require call stack)
* Built-in functions (require native code)
* Run Python tutorial example code <= We're here
* Exceptions
* GC
* Run popular libraries
---
class: center, middle, bleed, text-bg
background-image: url('pic/car_cutaway.jpg')
# Python Internals
---
### How Python VM works
* Stack machine
* Call stack and frames
* Has a NAMES list and CONSTS list
* Has a STACK as workspace
* Accepts Python bytecode
* `python -m dis source.py`
---
### A simple Python code
```
#!/usr/bin/env python3
print(1+1)
```
Running `python3 -m dis source.py` gives us
```
1 0 LOAD_NAME 0 (print)
3 LOAD_CONST 2 (2)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
```
---
### LOAD_NAME "print"
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### LOAD_CONST 2
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| 2 |
| print (native code)|
+--------------------+
```
---
### CALL_FUNCTION 1
1. `argument = stack.pop()` (argument == 2)
2. `function = stack.top()` (function == print)
3. call `print(2)`
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### POP_TOP
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| (empty) |
+--------------------+
```
---
### LOAD_CONST None
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| None |
+--------------------+
```
---
### RETURN_VALUE
(returns top of stack == None)
---
class: center, middle, bleed, text-bg
background-image: url('pic/electronic_parts.jpg')
# Technical Detail
---
### Bytecode format
* `dis` output format is for human reader
* Implementing a `dis` format parser is a waste of time
* Emit JSON bytecode using the [bytecode](https://pypi.python.org/pypi/bytecode/0.5) module
```
code = compile(f,...) # Python built-in, return a Code object
bytecode.Bytecode()
.from_code(code)
.to_concrete_bytecode()
```
* Load into Rust using `serde_json`
---
### Types
* Everything is a `PyObject` in CPython
* We'll need that class hierarchy eventually
* Use a Rust `enum` for now
```
pub enum NativeType{
NoneType,
Boolean(bool),
Int(i32),
Str(String),
Tuple(Vec<NativeType>),
...
}
```
---
### Testing
* `assert` is essential to for unittests
* `assert` raises `AssertionError`
* Use `panic!()` before we implement exception
```
assert 1 == 1
```
```
1 0 LOAD_CONST 0 (1)
3 LOAD_CONST 0 (1)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_TRUE 18
12 LOAD_GLOBAL 0 (AssertionError)
15 RAISE_VARARGS 1
>> 18 LOAD_CONST 1 (None)
21 RETURN_VALUE
```
---
### Native Function
* e.g. `print()`
```
pub enum NativeType {
NativeFunction(fn(Vec<NativeType>) -> NativeType),
...
}
match stack.pop() {
NativeFunction(func) => return_val = func(),
_ => ...
}
```
---
### Next steps
* Exceptions
* Make it run a small but popular tool/library
* Implement the parser
* Figure out garbage collection
* Performance benchmarking
---
### Contribute
## https://github.com/shinglyu/RustPython
![qr_code](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAACUCAYAAAB1PADUAAADeElEQVR4nO3dQY7jOBBFwfGg73/l6r02GiIfKbkmYlu2pDI+iARJJT8/Pz8//0Dk36cfgN9FoEgJFCmBIiVQpASKlECREihSAkVKoEgJFCmBIiVQpASKlECR+jO9wOfzKZ7jP1vdvnX3fNfrXT9/d7/6/797nt2m2+OMUKQEipRAkRrXUFf1FvXVGmK1Bpre/3QN9vTve8cIRUqgSAkUqbyGutpdI9Q11nQeaLWm2l3jXe1+DdMIRUqgSAkUqe011NtM54VWvz+dp/o2RihSAkVKoEj972qoet5mtWZa/f63MUKREihSAkVqew31tppgWuOsXm/3//+239cIRUqgSAkUqbyGOv0e2dW0pln9/u6/Xz39+94xQpESKFICRerz7We9nJ4nmu6X+u2MUKQEipRAkcr7Q+3ub7T7vbbd13t63sl7eXwVgSIlUKSO7ymf7tG++/zq/aa9CKb7qeoabjqvpscmryJQpASKVL6Wd3pe6s7uflP1/Z6ugaaMUKQEipRAkRrXUHUPyrvPT++/avda3O6+46ffGzRCkRIoUgJFaryWV88zvW3eajqvVq9drjo9T2WEIiVQpASK1Ov6Q+1eC6xroFXT/VN3nl4LNEKREihSAkVqe2+Dae+Bpz9/NV3Le3ot0zwUX0WgSAkUqe29Daama2tP77eazqOdPptmyghFSqBICRSp433K6/1G9fVXexmc7q2we15ryghFSqBICRSp1+0p392D8m37ke5M+0ud7k9lhCIlUKQEitTxHpt3Tr+LX897Te93+r1Ea3m8mkCREihSx9/L230GcG11La8+K+buee7oD8VXEyhSAkVqe5/y006fJfM2p+fVroxQpASKlECR2t7bYLenz+Tdvee9vv8dNRSvIlCkBIpU3ttgt+kZwE/3Gpje7/SZxKuMUKQEipRAkcr3Q739vbSna5hV0/1PV7t7HxihSAkUKYEitX1P+en9OG/vc17XeHecl8dXEyhSAkXqdb0Npt5Wg02vv2ra/8o8FK8iUKQEitSvq6F29/ne3aPz6f1lU0YoUgJFSqBIHe8P9fbr1/uJ6rNZdteIU0YoUgJFSqBIHT8v7/T9Tp/BO61x7q63+35TRihSAkVKoEh9fX8o3sUIRUqgSAkUKYEiJVCkBIqUQJESKFICRUqgSAkUKYEiJVCkBIqUQJH6C+akK0TJ2q/FAAAAAElFTkSuQmCC)
---
class: middle, center
# Thank you
---
### References
* [`dis` documentation](https://docs.python.org/3.4/library/dis.html)
* [byterun](http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html)
* [byterun (GitHub)](https://github.com/nedbat/byterun/)
* [cpython source code](https://github.com/python/cpython)
</textarea>
<!-- autoreload -->
<script type="text/javascript">
/* Force all links to be opened in new tab/window */
window.addEventListener('load', function(){
var links = document.getElementsByTagName('a');
var linksList = Array.prototype.slice.call(links);
linksList.forEach(function(anchor_elem){
anchor_elem.setAttribute('target', '_blank');
});
});
</script>
<script type="text/javascript">
document.write(unescape("%3Cscript type='text/javascript'%3E" + "require%3Dfunction%28e%2Ct%2Cr%29%7Bfunction%20a%28r%2Cn%29%7Bif%28%21t%5Br%5D%29%7Bif%28%21e%5Br%5D%29%7Bvar%20s%3D%22function%22%3D%3Dtypeof%20require%26%26require%3Bif%28%21n%26%26s%29return%20s%28r%2C%210%29%3Bif%28i%29return%20i%28r%2C%210%29%3Bthrow%20new%20Error%28%22Cannot%20find%20module%20%27%22+r+%22%27%22%29%7Dvar%20l%3Dt%5Br%5D%3D%7Bexports%3A%7B%7D%7D%3Be%5Br%5D%5B0%5D.call%28l.exports%2Cfunction%28t%29%7Bvar%20i%3De%5Br%5D%5B1%5D%5Bt%5D%3Breturn%20a%28i%3Fi%3At%29%7D%2Cl%2Cl.exports%29%7Dreturn%20t%5Br%5D.exports%7Dfor%28var%20i%3D%22function%22%3D%3Dtypeof%20require%26%26require%2Cn%3D0%3Bn%3Cr.length%3Bn++%29a%28r%5Bn%5D%29%3Breturn%20a%7D%28%7B%22components/printing%22%3A%5Bfunction%28e%2Ct%29%7Bt.exports%3De%28%22yoGRCZ%22%29%7D%2C%7B%7D%5D%2CyoGRCZ%3A%5Bfunction%28e%2Ct%29%7Bfunction%20r%28%29%7B%7Dvar%20a%3De%28%22events%22%29.EventEmitter%2Ci%3De%28%22components/styler%22%29%2Cn%3D%22landscape%22%2Cs%3D%22portrait%22%2Cl%3D681%2Co%3D908%3Br.prototype%3Dnew%20a%2Cr.prototype.init%3Dfunction%28%29%7Bvar%20e%3Dthis%3Breturn%20this.setPageOrientation%28n%29%2Cwindow.matchMedia%3F%28window.matchMedia%28%22print%22%29.addListener%28function%28t%29%7Be.onPrint%28t%29%7D%29%2Cvoid%200%29%3A%211%7D%2Cr.prototype.onPrint%3Dfunction%28e%29%7Be.matches%26%26this.emit%28%22print%22%2C%7BisPortrait%3A%22portrait%22%3D%3D%3Dthis._orientation%2CpageHeight%3Athis._pageHeight%2CpageWidth%3Athis._pageWidth%7D%29%7D%2Cr.prototype.setPageOrientation%3Dfunction%28e%29%7Bif%28e%3D%3D%3Ds%29this._pageHeight%3Do%2Cthis._pageWidth%3Dl%3Belse%7Bif%28e%21%3D%3Dn%29throw%20new%20Error%28%22Unknown%20print%20orientation%3A%20%22+e%29%3Bthis._pageHeight%3Dl%2Cthis._pageWidth%3Do%7Dthis._orientation%3De%2Ci.setPageSize%28this._pageWidth+%22px%20%22+this._pageHeight+%22px%22%29%7D%2Ct.exports%3Dnew%20r%7D%2C%7Bevents%3A1%2C%22components/styler%22%3A%22syTcZF%22%7D%5D%2C%22components/slide-number%22%3A%5Bfunction%28e%2Ct%29%7Bt.exports%3De%28%22GSZq7a%22%29%7D%2C%7B%7D%5D%2CGSZq7a%3A%5Bfunction%28e%2Ct%29%7Bfunction%20r%28e%2Ct%29%7Bvar%20r%3Dthis%3Br.slide%3De%2Cr.slideshow%3Dt%2Cr.element%3Ddocument.createElement%28%22div%22%29%2Cr.element.className%3D%22remark-slide-number%22%2Cr.element.innerHTML%3Da%28r.slide%2Cr.slideshow%29%7Dfunction%20a%28e%2Ct%29%7Bvar%20r%3Dt.getSlideNumberFormat%28%29%2Ca%3Dt.getSlides%28%29%2Cn%3Di%28e%2Ct%29%2Cs%3Di%28a%5Ba.length-1%5D%2Ct%29%3Breturn%22function%22%3D%3Dtypeof%20r%3Fr.call%28t%2Cn%2Cs%29%3Ar.replace%28%22%25current%25%22%2Cn%29.replace%28%22%25total%25%22%2Cs%29%7Dfunction%20i%28e%2Ct%29%7Bvar%20r%2Ca%3Dt.getSlides%28%29%2Ci%3D0%3Bfor%28r%3D0%3Br%3C%3De.getSlideIndex%28%29%26%26r%3Ca.length%3B++r%29%22false%22%21%3D%3Da%5Br%5D.properties.count%26%26%28i+%3D1%29%3Breturn%20Math.max%281%2Ci%29%7Dt.exports%3Dr%7D%2C%7B%7D%5D%2C2%3A%5Bfunction%28e%2Ct%29%7Bvar%20r%3Dt.exports%3D%7B%7D%3Br.nextTick%3Dfunction%28%29%7Bvar%20e%3D%22undefined%22%21%3Dtypeof%20window%26%26window.setImmediate%2Ct%3D%22undefined%22%21%3Dtypeof%20window%26%26window.postMessage%26%26window.addEventListener%3Bif%28e%29return%20function%28e%29%7Breturn%20window.setImmediate%28e%29%7D%3Bif%28t%29%7Bvar%20r%3D%5B%5D%3Breturn%20window.addEventListener%28%22message%22%2Cfunction%28e%29%7Bvar%20t%3De.source%3Bif%28%28t%3D%3D%3Dwindow%7C%7Cnull%3D%3D%3Dt%29%26%26%22process-tick%22%3D%3D%3De.data%26%26%28e.stopPropagation%28%29%2Cr.length%3E0%29%29%7Bvar%20a%3Dr.shift%28%29%3Ba%28%29%7D%7D%2C%210%29%2Cfunction%28e%29%7Br.push%28e%29%2Cwindow.postMessage%28%22process-tick%22%2C%22*%22%29%7D%7Dreturn%20function%28e%29%7BsetTimeout%28e%2C0%29%7D%7D%28%29%2Cr.title%3D%22browser%22%2Cr.browser%3D%210%2Cr.env%3D%7B%7D%2Cr.argv%3D%5B%5D%2Cr.binding%3Dfunction%28%29%7Bthrow%20new%20Error%28%22process.binding%20is%20not%20supported%22%29%7D%2Cr.cwd%3Dfunction%28%29%7Breturn%22/%22%7D%2Cr.chdir%3Dfunction%28%29%7Bthrow%20new%20Error%28%22process.chdir%20is%20not%20supported%22%29%7D%7D%2C%7B%7D%5D%2C1%3A%5Bfunction%28e%2Ct%2Cr%29%7B%21function%28e%29%7Bfunction%20t%28e%2Ct%29%7Bif%28e.indexOf%29return%20e.indexOf%28t%29%3Bfor%28var%20r%3D0%3Br%3Ce.length%3Br++%29if%28t%3D%3D%3De%5Br%5D%29return%20r%3Breturn-1%7De.EventEmitter%7C%7C%28e.EventEmitter%3Dfunction%28%29%7B%7D%29%3Bvar%20a%3Dr.EventEmitter%3De.EventEmitter%2Ci%3D%22function%22%3D%3Dtypeof%20Array.isArray%3FArray.isArray%3Afunction%28e%29%7Breturn%22%5Bobject%20Array%5D%22%3D%3D%3DObject.prototype.toString.call%28e%29%7D%2Cn%3D10%3Ba.prototype.setMaxListeners%3Dfunction%28e%29%7Bthis._events%7C%7C%28this._events%3D%7B%7D%29%2Cthis._events.maxListeners%3De%7D%2Ca.prototype.emit%3Dfunction%28e%29%7Bif%28%22error%22%3D%3D%3De%26%26%28%21this._events%7C%7C%21this._events.error%7C%7Ci%28this._events.error%29%26%26%21this._events.error.length%29%29throw%20arguments%5B1%5Dinstanceof%20Error%3Farguments%5B1%5D%3Anew%20Error%28%22Uncaught%2C%20unspecified%20%27error%27%20event.%22%29%3Bif%28%21thisLine truncated
</script>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

-286
View File
@@ -1,286 +0,0 @@
class: center, middle
##Python Interpreter in Rust
#### 2017/8/6, COSCUP
#### Shing Lyu
???
top, middle, bottom
left, center, right
---
### About Me
* 呂行 Shing Lyu
* Mozilla engineer
* Servo team
![rust_and_servo](pic/rust-servo.png)
---
### Python's architecture
* Interpreted
* Garbage Collected
* Compiler => bytecode => VM
![python](pic/python-logo.png)
---
background-image: url('pic/ice-cream.jpg')
class: center, middle, bleed, text-bg
# Flavors
---
### Python Flavors
* CPython (THE python)
* Jython (JVM)
* IronPython (.NET)
* Pypy
* Educational
* Byterun
* Jsapy (JS)
* Brython (Python in browser)
---
class: center, middle
# Why & How?
---
### Why rewriting Python in Rust?
* Memory safety (?)
* Learn about Python's internal
* Learn to write Rust from scratch
* FUN!
---
### Implementation strategy
* Mostly follow CPython 3.6
* Focus on the VM first, then the compiler
* Use the Python built-in compiler to generate bytecode
* Focus on learning rather than usability
---
### Milestones
* Basic arithmetics
* Variables
* Control flows (require JUMP)
* Function call (require call stack)
* Built-in functions (require native code)
* Run Python tutorial example code <= We're here
* Exceptions
* GC
* Run popular libraries
---
class: center, middle, bleed, text-bg
background-image: url('pic/car_cutaway.jpg')
# Python Internals
---
### How Python VM works
* Stack machine
* Call stack and frames
* Has a NAMES list and CONSTS list
* Has a STACK as workspace
* Accepts Python bytecode
* `python -m dis source.py`
---
### A simple Python code
```
#!/usr/bin/env python3
print(1+1)
```
Running `python3 -m dis source.py` gives us
```
1 0 LOAD_NAME 0 (print)
3 LOAD_CONST 2 (2)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
```
---
### LOAD_NAME "print"
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### LOAD_CONST 2
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| 2 |
| print (native code)|
+--------------------+
```
---
### CALL_FUNCTION 1
1. `argument = stack.pop()` (argument == 2)
2. `function = stack.top()` (function == print)
3. call `print(2)`
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### POP_TOP
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| (empty) |
+--------------------+
```
---
### LOAD_CONST None
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| None |
+--------------------+
```
---
### RETURN_VALUE
(returns top of stack == None)
---
class: center, middle, bleed, text-bg
background-image: url('pic/electronic_parts.jpg')
# Technical Detail
---
### Bytecode format
* `dis` output format is for human reader
* Implementing a `dis` format parser is a waste of time
* Emit JSON bytecode using the [bytecode](https://pypi.python.org/pypi/bytecode/0.5) module
```
code = compile(f,...) # Python built-in, return a Code object
bytecode.Bytecode()
.from_code(code)
.to_concrete_bytecode()
```
* Load into Rust using `serde_json`
---
### Types
* Everything is a `PyObject` in CPython
* We'll need that class hierarchy eventually
* Use a Rust `enum` for now
```
pub enum NativeType{
NoneType,
Boolean(bool),
Int(i32),
Str(String),
Tuple(Vec<NativeType>),
...
}
```
---
### Testing
* `assert` is essential to for unittests
* `assert` raises `AssertionError`
* Use `panic!()` before we implement exception
```
assert 1 == 1
```
```
1 0 LOAD_CONST 0 (1)
3 LOAD_CONST 0 (1)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_TRUE 18
12 LOAD_GLOBAL 0 (AssertionError)
15 RAISE_VARARGS 1
>> 18 LOAD_CONST 1 (None)
21 RETURN_VALUE
```
---
### Native Function
* e.g. `print()`
```
pub enum NativeType {
NativeFunction(fn(Vec<NativeType>) -> NativeType),
...
}
match stack.pop() {
NativeFunction(func) => return_val = func(),
_ => ...
}
```
---
### Next steps
* Exceptions
* Make it run a small but popular tool/library
* Implement the parser
* Figure out garbage collection
* Performance benchmarking
---
### Contribute
## https://github.com/shinglyu/RustPython
![qr_code](pic/repo_QR.png)
---
class: middle, center
# Thank you
---
### References
* [`dis` documentation](https://docs.python.org/3.4/library/dis.html)
* [byterun](http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html)
* [byterun (GitHub)](https://github.com/nedbat/byterun/)
* [cpython source code](https://github.com/python/cpython)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

-180
View File
@@ -1,180 +0,0 @@
class: center, middle
##Python Interpreter in Rust
###Introduction
#### 2017/3/28
#### Shing Lyu
???
top, middle, bottom
left, center, right
---
name: toc
###Agenda
1. Category
1. Category
1. Category
1. Category
1. Category
1. Category
1. Category
???
This is a template
---
### Python's architecture
* Interpreted
* Garbage Collected
* Compiler => bytecode => VM
---
background-image: url('pic/ice-cream.jpg')
class: bleed
# Flavors
---
### Python Flavors
* CPython (THE python)
* Jython (JVM)
* IronPython (.NET)
* Pypy
* Educational
* Byterun
* Jsapy (JS)
* Brython (Python in browser)
---
### Why rewriting Python in Rust?
* Memory safety
* Learn about Python internal
* Learn real world Rust
---
### Implementation strategy
* Focus on the VM first, then the compiler
* Reuse the Python built-in compiler to generate bytecode
* Basic arithmetics
* Control flows (require JUMP)
* Function call (require call stack)
* Built-in functions (require native code)
* Run popular libraries
---
### References
* [`dis` documentation](https://docs.python.org/3.4/library/dis.html)
* [byterun](http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html)
* [byterun (GitHub)](https://github.com/nedbat/byterun/)
* [cpython source code](https://github.com/python/cpython)
---
### How Python VM works
* Stack machine
* Accepts Python bytecode
* `python -m dis source.py`
---
### A simple Python code
```
#!/usr/bin/env python3
print(1+1)
```
We run `python3 -m dis source.py`
---
### The bytecode
```
1 0 LOAD_NAME 0 (print)
3 LOAD_CONST 2 (2)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
```
---
### LOAD_NAME "print"
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### LOAD_CONST 2
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| 2 |
| print (native code)|
+--------------------+
```
---
### CALL_FUNCTION 1
1. argument = stack.pop() (argument == 2)
2. function = stack.top() (function == print)
3. call print(2)
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| print (native code)|
+--------------------+
```
---
### POP_TOP
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| (empty) |
+--------------------+
```
---
### LOAD_CONST 1
* NAMES = ["print"]
* CONSTS = [None, 2]
* STACK:
```
| |
| None |
+--------------------+
```
---
### RETURN_VALUE
(returns top of stack == None)
---
### Next step
* Make it run a small but popular tool/library
* Implement the parser
* Performance benchmarking
-6
View File
@@ -1,6 +0,0 @@
Topic to study
==================
* How to save a Rust Iterator on the stack?
* Study how blocks are handled in CPython.
* The `why` var?
* Why unwind everything when a `break` happened?
+1 -1
View File
@@ -10,4 +10,4 @@ pytest = "*"
[dev-packages]
[requires]
python_version = "3.6"
python_version = "3"
+72
View File
@@ -0,0 +1,72 @@
# Compiling to webassembly
At this stage RustPython only has preliminary support for web assembly. The instructions here are intended for developers or those wishing to run a toy example.
## Setup
To get started, install [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) and `npm`. ([wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/whirlwind-tour/basic-usage.html) should be installed by `wasm-pack`. if not, install it yourself)
<!-- Using `rustup` add the compile target `wasm32-unknown-emscripten`. To do so you will need to have [rustup](https://rustup.rs/) installed.
```bash
rustup target add wasm32-unknown-emscripten
```
Next, install `emsdk`:
```bash
curl https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | tar -zxv
cd emsdk-portable/
./emsdk update
./emsdk install sdk-incoming-64bit
./emsdk activate sdk-incoming-64bit
``` -->
## Build
Move into the `wasm` directory. This directory contains a library crate for interop
with python to rust to js and back in `wasm/lib`, the demo website found at
https://rustpython.github.io/demo in `wasm/demo`, and an example of how to use
the crate as a library in one's own JS app in `wasm/example`.
```sh
cd wasm
```
Go to the demo directory. This is the best way of seeing the changes made to either
the library or the JS demo, as the `rustpython_wasm` module is set to the global
JS variable `rp` on the website.
```sh
cd demo
```
Now, start the webpack development server. It'll compile the crate and then
the demo app. This will likely take a long time, both the wasm-pack portion and
the webpack portion (from after it says "Your crate has been correctly compiled"),
so be patient.
```sh
npm run dev
```
You can now open the webpage on https://localhost:8080 and Python code in either
the text box or browser devtools with:
```js
rp.pyEval(
`
print(js_vars['a'] * 9)
`,
{
vars: {
a: 9
}
}
);
```
Alternatively, you can run `npm run build` to build the app once, without watching
for changes, or `npm run dist` to build the app in release mode, both for the
crate and webpack.