mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
96eaeb49f5
commit
57574bd8be
114
docs/features/precompile.md
Normal file
114
docs/features/precompile.md
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
icon: dot
|
||||||
|
title: Precompiling
|
||||||
|
---
|
||||||
|
|
||||||
|
pkpy allows you to precompile your python code into a special form, which can be executed later.
|
||||||
|
|
||||||
|
### In-memory precompilation
|
||||||
|
|
||||||
|
You can use `vm->compile` to compile your source code into a `CodeObject_` object.
|
||||||
|
This object can be executed later by `vm->_exec`.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
CodeObject_ code = vm->compile("print('Hello, world!')", "<string>", EXEC_MODE);
|
||||||
|
vm->_exec(code); // Hello, world!
|
||||||
|
```
|
||||||
|
|
||||||
|
This `CodeObject_` object is a very non-generic form of the compiled code.
|
||||||
|
It is an in-memory form. You are not able to save it to a file or load it from a file.
|
||||||
|
|
||||||
|
|
||||||
|
### String precompilation
|
||||||
|
|
||||||
|
In order to save the compiled code to a file, you need to use `vm->precompile`.
|
||||||
|
It does some basic preprocessing and outputs the result as a human-readable string.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// precompile the source code into a string
|
||||||
|
Str source = vm->precompile("print('Hello, world!')", "<string>", EXEC_MODE);
|
||||||
|
|
||||||
|
CodeObject code = vm->compile(source, "<string>", EXEC_MODE);
|
||||||
|
vm->_exec(code); // Hello, world!
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use python's `compile` function to achieve the same effect.
|
||||||
|
|
||||||
|
```python
|
||||||
|
code = compile("print('Hello, world!')", "<string>", "exec")
|
||||||
|
exec(code) # Hello, world!
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's take a look at the precompiled string.
|
||||||
|
```python
|
||||||
|
print(code)
|
||||||
|
```
|
||||||
|
|
||||||
|
```txt
|
||||||
|
pkpy:1.4.4
|
||||||
|
0
|
||||||
|
|print|
|
||||||
|
=6
|
||||||
|
5,1,0,
|
||||||
|
6,1,5,1,0,
|
||||||
|
42,1,1,
|
||||||
|
8,1,1,S48656c6c6f2c20776f726c6421
|
||||||
|
43,1,0,
|
||||||
|
3,1,0,
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Comparing with **In-memory precompilation**,
|
||||||
|
**String precompilation** drops most of the original source code.
|
||||||
|
It has an encryption effect, which can protect your source code from being stolen.
|
||||||
|
It also means there is no source line information when an error occurs.
|
||||||
|
|
||||||
|
```python
|
||||||
|
src = """
|
||||||
|
def f(a, b):
|
||||||
|
return g(a, b)
|
||||||
|
|
||||||
|
def g(a, b):
|
||||||
|
c = f(a, b)
|
||||||
|
d = g(a, b)
|
||||||
|
return c + d
|
||||||
|
"""
|
||||||
|
|
||||||
|
code = compile(src, "<exec>", "exec")
|
||||||
|
exec(code)
|
||||||
|
f(1, 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
You will get this (without source line information):
|
||||||
|
```txt
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<exec>", line 3, in f
|
||||||
|
File "<exec>", line 6, in g
|
||||||
|
File "<exec>", line 3, in f
|
||||||
|
File "<exec>", line 6, in g
|
||||||
|
File "<exec>", line 3, in f
|
||||||
|
File "<exec>", line 6, in g
|
||||||
|
File "<exec>", line 3, in f
|
||||||
|
StackOverflowError
|
||||||
|
```
|
||||||
|
|
||||||
|
instead of this (with source line information):
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 2, in f
|
||||||
|
return g(a, b)
|
||||||
|
File "<stdin>", line 2, in g
|
||||||
|
c = f(a, b)
|
||||||
|
File "<stdin>", line 2, in f
|
||||||
|
return g(a, b)
|
||||||
|
File "<stdin>", line 2, in g
|
||||||
|
c = f(a, b)
|
||||||
|
File "<stdin>", line 2, in f
|
||||||
|
return g(a, b)
|
||||||
|
File "<stdin>", line 2, in g
|
||||||
|
c = f(a, b)
|
||||||
|
File "<stdin>", line 2, in f
|
||||||
|
return g(a, b)
|
||||||
|
StackOverflowError
|
||||||
|
```
|
@ -1,2 +1,16 @@
|
|||||||
code = compile("1+2", "<eval>", "eval")
|
code = compile("1+2", "<eval>", "eval")
|
||||||
assert eval(code) == 3
|
assert eval(code) == 3
|
||||||
|
|
||||||
|
src = """
|
||||||
|
def f(a, b):
|
||||||
|
return g(a, b)
|
||||||
|
|
||||||
|
def g(a, b):
|
||||||
|
c = f(a, b)
|
||||||
|
d = g(a, b)
|
||||||
|
return c + d
|
||||||
|
"""
|
||||||
|
|
||||||
|
code = compile(src, "<12>", "exec")
|
||||||
|
exec(code)
|
||||||
|
f(1, 2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user