Skip to content

Commit a9058f0

Browse files
committed
Add a separate crate to package the python stdlib source code with
1 parent bc1717b commit a9058f0

File tree

8 files changed

+90
-22
lines changed

8 files changed

+90
-22
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repository = "https://github.com/RustPython/RustPython"
88
license = "MIT"
99

1010
[workspace]
11-
members = [".", "derive", "vm", "wasm/lib", "parser", "compiler", "bytecode", "examples/freeze"]
11+
members = [".", "derive", "vm", "wasm/lib", "parser", "compiler", "bytecode", "examples/freeze", "vm/pylib-crate"]
1212

1313
[[bench]]
1414
name = "bench"

derive/src/compile_bytecode.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,11 @@ struct PyCompileInput {
157157
}
158158

159159
impl PyCompileInput {
160-
fn compile(&self) -> Result<HashMap<String, FrozenModule>, Diagnostic> {
160+
fn parse(&self) -> Result<PyCompileArgs, Diagnostic> {
161161
let mut module_name = None;
162162
let mut mode = None;
163163
let mut source: Option<CompilationSource> = None;
164+
let mut crate_name = None;
164165

165166
fn assert_source_empty(source: &Option<CompilationSource>) -> Result<(), Diagnostic> {
166167
if let Some(source) = source {
@@ -222,21 +223,29 @@ impl PyCompileInput {
222223
kind: CompilationSourceKind::Dir(path),
223224
span: extract_spans(&name_value).unwrap(),
224225
});
226+
} else if ident == "crate_name" {
227+
let name = match &name_value.lit {
228+
Lit::Str(s) => syn::Ident::new(&s.value(), s.span()),
229+
_ => bail_span!(name_value.lit, "source must be a string"),
230+
};
231+
crate_name = Some(name);
225232
}
226233
}
227234
}
228235

229-
source
230-
.ok_or_else(|| {
231-
Diagnostic::span_error(
232-
self.span,
233-
"Must have either file or source in py_compile_bytecode!()",
234-
)
235-
})?
236-
.compile(
237-
mode.unwrap_or(compile::Mode::Exec),
238-
module_name.unwrap_or_else(|| "frozen".to_owned()),
236+
let source = source.ok_or_else(|| {
237+
Diagnostic::span_error(
238+
self.span,
239+
"Must have either file or source in py_compile_bytecode!()",
239240
)
241+
})?;
242+
243+
Ok(PyCompileArgs {
244+
source,
245+
mode: mode.unwrap_or(compile::Mode::Exec),
246+
module_name: module_name.unwrap_or_else(|| "frozen".to_owned()),
247+
crate_name: crate_name.unwrap_or_else(|| syn::parse_quote!(rustpython_vm)),
248+
})
240249
}
241250
}
242251

@@ -251,10 +260,19 @@ impl Parse for PyCompileInput {
251260
}
252261
}
253262

263+
struct PyCompileArgs {
264+
source: CompilationSource,
265+
mode: compile::Mode,
266+
module_name: String,
267+
crate_name: syn::Ident,
268+
}
269+
254270
pub fn impl_py_compile_bytecode(input: TokenStream2) -> Result<TokenStream2, Diagnostic> {
255271
let input: PyCompileInput = parse2(input)?;
272+
let args = input.parse()?;
256273

257-
let code_map = input.compile()?;
274+
let crate_name = args.crate_name;
275+
let code_map = args.source.compile(args.mode, args.module_name)?;
258276

259277
let modules = code_map
260278
.into_iter()
@@ -263,8 +281,8 @@ pub fn impl_py_compile_bytecode(input: TokenStream2) -> Result<TokenStream2, Dia
263281
let bytes = code.to_bytes();
264282
let bytes = LitByteStr::new(&bytes, Span::call_site());
265283
quote! {
266-
#module_name.into() => ::rustpython_vm::bytecode::FrozenModule {
267-
code: ::rustpython_vm::bytecode::CodeObject::from_bytes(
284+
#module_name.into() => ::#crate_name::bytecode::FrozenModule {
285+
code: ::#crate_name::bytecode::CodeObject::from_bytes(
268286
#bytes
269287
).expect("Deserializing CodeObject failed"),
270288
package: #package,
@@ -274,7 +292,7 @@ pub fn impl_py_compile_bytecode(input: TokenStream2) -> Result<TokenStream2, Dia
274292

275293
let output = quote! {
276294
({
277-
use ::rustpython_vm::__exports::hashmap;
295+
use ::#crate_name::__exports::hashmap;
278296
hashmap! {
279297
#(#modules),*
280298
}

vm/Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
1212
default = ["rustpython-parser", "rustpython-compiler"]
1313
vm-tracing-logging = []
1414
flame-it = ["flame", "flamer"]
15-
freeze-stdlib = []
15+
freeze-stdlib = ["rustpython-pylib"]
1616

1717
ssl = ["openssl", "openssl-sys", "openssl-probe"]
1818

@@ -37,10 +37,11 @@ rand_core = "0.5"
3737
getrandom = { version = "0.1", features = ["wasm-bindgen"] }
3838
mt19937 = "1.0"
3939
log = "0.4"
40-
rustpython-derive = {path = "../derive", version = "0.1.1"}
41-
rustpython-parser = {path = "../parser", optional = true, version = "0.1.1"}
42-
rustpython-compiler = {path = "../compiler", optional = true, version = "0.1.1"}
43-
rustpython-bytecode = { path = "../bytecode", version = "0.1.1"}
40+
rustpython-derive = { path = "../derive", version = "0.1.2" }
41+
rustpython-parser = { path = "../parser", optional = true, version = "0.1.2" }
42+
rustpython-compiler = { path = "../compiler", optional = true, version = "0.1.2" }
43+
rustpython-bytecode = { path = "../bytecode", version = "0.1.2" }
44+
rustpython-pylib = { path = "pylib-crate", optional = true, version = "0.1.0" }
4445
serde = { version = "1.0.66", features = ["derive"] }
4546
byteorder = "1.2.6"
4647
regex = "1"

vm/pylib-crate/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "rustpython-pylib"
3+
version = "0.1.0"
4+
authors = ["Noah <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
rustpython-derive = { version = "0.1.2", path = "../../derive" }
9+
rustpython-bytecode = { version = "0.1.2", path = "../../bytecode" }
10+
maplit = "1.0"

vm/pylib-crate/Lib

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../Lib/

vm/pylib-crate/src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! This crate includes the compiled python bytecode of the RustPython standard library. The most
2+
//! common way to use this crate is to just add the `"freeze-stdlib"` feature to `rustpython-vm`,
3+
//! in order to automatically include the python part of the standard library into the binary.
4+
5+
extern crate self as rustpython_pylib;
6+
7+
use rustpython_bytecode::bytecode::{self, FrozenModule};
8+
use std::collections::HashMap;
9+
10+
use rustpython_derive::py_compile_bytecode as _py_compile_bytecode;
11+
#[macro_export]
12+
macro_rules! py_compile_bytecode {
13+
($($arg:tt)*) => {{
14+
#[macro_use]
15+
mod __m {
16+
$crate::_py_compile_bytecode!($($arg)*);
17+
}
18+
__proc_macro_call!()
19+
}};
20+
}
21+
22+
mod __exports {
23+
pub use maplit::hashmap;
24+
}
25+
26+
pub fn frozen_stdlib() -> HashMap<String, FrozenModule> {
27+
py_compile_bytecode!(dir = "Lib", crate_name = "rustpython_pylib")
28+
}

vm/src/frozen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn get_module_inits() -> HashMap<String, FrozenModule> {
2929
// if we're on freeze-stdlib, the core stdlib modules will be included anyway
3030
#[cfg(feature = "freeze-stdlib")]
3131
{
32-
ext_modules!(dir = "../Lib/");
32+
modules.extend(rustpython_pylib::frozen_stdlib());
3333
}
3434

3535
modules

0 commit comments

Comments
 (0)