Merge pull request #2397 from RustPython/coolreader18/fasthash

Use ahash instead of siphash in a few places
This commit is contained in:
Jeong YunWon
2021-01-11 01:37:12 +09:00
committed by GitHub
25 changed files with 273 additions and 141 deletions

204
Cargo.lock generated
View File

@@ -24,6 +24,23 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "ahash"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]]
name = "ahash"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75b7e6a93ecd6dbd2c225154d0fa7f86205574ecaa6c87429fb5f66ee677c44"
dependencies = [
"getrandom 0.2.1",
"lazy_static 1.4.0",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.15"
@@ -273,7 +290,7 @@ dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim 0.8.0",
"strsim",
"textwrap 0.11.0",
"unicode-width",
"vec_map",
@@ -531,6 +548,12 @@ dependencies = [
"lazy_static 1.4.0",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-mac"
version = "0.7.0"
@@ -650,18 +673,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "docopt"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
dependencies = [
"lazy_static 1.4.0",
"regex",
"serde",
"strsim 0.9.3",
]
[[package]]
name = "dtoa"
version = "0.4.6"
@@ -871,6 +882,9 @@ name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash 0.4.7",
]
[[package]]
name = "hermit-abi"
@@ -983,34 +997,35 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
[[package]]
name = "lalrpop"
version = "0.19.1"
version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60fb56191fb8ed5311597e5750debe6779c9fdb487dbaa5ff302592897d7a2c8"
checksum = "4a71d75b267b3299da9ccff4dd80d73325b5d8adcd76fe97cf92725eb7c6f122"
dependencies = [
"ascii-canvas",
"atty",
"bit-set",
"diff",
"docopt",
"ena",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"serde",
"serde_derive",
"sha2",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.19.1"
version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6771161eff561647fad8bb7e745e002c304864fb8f436b52b30acda51fca4408"
checksum = "3ebbd90154472db6267a7d28ca08fea7788e5619fef10f2398155cb74c08f77a"
dependencies = [
"regex",
]
[[package]]
name = "lazy_static"
@@ -1102,13 +1117,9 @@ dependencies = [
[[package]]
name = "lz4_flex"
version = "0.5.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50e76831e3b044ebf7008b17d6083e4dda6d8a9f6839387d7a81fad549417f57"
dependencies = [
"byteorder",
"quick-error",
]
checksum = "a9025814971d70dd729afe3b93b02d653c905dadb9821d5578458e12dea5148f"
[[package]]
name = "mach"
@@ -1179,7 +1190,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e6dd1b4462edbfbc0c4ad4c3205d94623bb94b4819aa0888936988d38834158"
dependencies = [
"rand_core",
"rand_core 0.6.0",
]
[[package]]
@@ -1411,6 +1422,41 @@ dependencies = [
"indexmap",
]
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
"phf_shared",
"proc-macro-hack",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand 0.7.3",
]
[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
@@ -1420,6 +1466,12 @@ dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1"
[[package]]
name = "pkg-config"
version = "0.3.19"
@@ -1516,6 +1568,20 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.15",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
"rand_pcg",
]
[[package]]
name = "rand"
version = "0.8.0"
@@ -1523,9 +1589,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_chacha 0.3.0",
"rand_core 0.6.0",
"rand_hc 0.3.0",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
@@ -1535,7 +1611,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.0",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.15",
]
[[package]]
@@ -1547,13 +1632,31 @@ dependencies = [
"getrandom 0.2.1",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core",
"rand_core 0.6.0",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
@@ -1762,7 +1865,7 @@ dependencies = [
"num-traits",
"once_cell",
"parking_lot",
"rand",
"rand 0.8.0",
"siphasher",
"volatile",
]
@@ -1781,7 +1884,7 @@ dependencies = [
name = "rustpython-compiler-core"
version = "0.1.2"
dependencies = [
"arrayvec",
"ahash 0.6.2",
"indexmap",
"insta",
"itertools",
@@ -1828,11 +1931,14 @@ dependencies = [
name = "rustpython-parser"
version = "0.1.2"
dependencies = [
"ahash 0.6.2",
"hashbrown",
"lalrpop",
"lalrpop-util",
"log",
"num-bigint",
"num-traits",
"phf",
"rustpython-ast",
"unic-emoji-char",
"unic-ucd-ident",
@@ -1852,6 +1958,7 @@ name = "rustpython-vm"
version = "0.1.2"
dependencies = [
"adler32",
"ahash 0.6.2",
"atty",
"base64",
"bitflags",
@@ -1883,7 +1990,6 @@ dependencies = [
"libc",
"libz-sys",
"log",
"maplit",
"md-5",
"mt19937",
"nix",
@@ -1901,8 +2007,8 @@ dependencies = [
"parking_lot",
"paste",
"puruspe",
"rand",
"rand_core",
"rand 0.8.0",
"rand_core 0.6.0",
"regex",
"result-like",
"rustc_version_runtime",
@@ -2163,7 +2269,6 @@ dependencies = [
"new_debug_unreachable",
"phf_shared",
"precomputed-hash",
"serde",
]
[[package]]
@@ -2172,12 +2277,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "subtle"
version = "1.0.0"
@@ -2324,6 +2423,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb4fa83bb73adf1c7219f4fe4bf3c0ac5635e4e51e070fad5df745a41bedfb8"
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "tinytemplate"
version = "1.1.0"
@@ -2556,6 +2664,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "volatile"
version = "0.3.0"

View File

@@ -11,7 +11,7 @@ license = "MIT"
[dependencies]
bincode = "1.1"
bitflags = "1.1"
lz4_flex = "0.5"
lz4_flex = "0.7"
num-bigint = { version = "0.3", features = ["serde"] }
num-complex = { version = "0.3", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }

View File

@@ -15,7 +15,7 @@ rustpython-ast = { path = "../ast" }
num-complex = { version = "0.3", features = ["serde"] }
num-traits = "0.2"
log = "0.4"
arrayvec = "0.5"
ahash = "0.6"
[dev-dependencies]
rustpython-parser = { path = "../parser" }

View File

@@ -9,7 +9,7 @@ use crate::error::{CompileError, CompileErrorType};
use crate::ir::{self, CodeInfo};
pub use crate::mode::Mode;
use crate::symboltable::{make_symbol_table, statements_to_symbol_table, SymbolScope, SymbolTable};
use indexmap::IndexSet;
use crate::IndexSet;
use itertools::Itertools;
use num_complex::Complex64;
use num_traits::ToPrimitive;
@@ -140,10 +140,10 @@ impl Compiler {
blocks: vec![ir::Block::default()],
current_block: bytecode::Label(0),
constants: Vec::new(),
name_cache: IndexSet::new(),
varname_cache: IndexSet::new(),
cellvar_cache: IndexSet::new(),
freevar_cache: IndexSet::new(),
name_cache: IndexSet::default(),
varname_cache: IndexSet::default(),
cellvar_cache: IndexSet::default(),
freevar_cache: IndexSet::default(),
};
Compiler {
code_stack: vec![module_code],
@@ -217,8 +217,8 @@ impl Compiler {
blocks: vec![ir::Block::default()],
current_block: bytecode::Label(0),
constants: Vec::new(),
name_cache: IndexSet::new(),
varname_cache: IndexSet::new(),
name_cache: IndexSet::default(),
varname_cache: IndexSet::default(),
cellvar_cache,
freevar_cache,
};

View File

@@ -1,4 +1,4 @@
use indexmap::IndexSet;
use crate::IndexSet;
use rustpython_bytecode::{CodeFlags, CodeObject, ConstantData, Instruction, Label, Location};
pub type BlockIdx = Label;

View File

@@ -5,6 +5,9 @@
#[macro_use]
extern crate log;
type IndexMap<K, V> = indexmap::IndexMap<K, V, ahash::RandomState>;
type IndexSet<T> = indexmap::IndexSet<T, ahash::RandomState>;
pub mod compile;
pub mod error;
pub mod ir;

View File

@@ -8,7 +8,7 @@ Inspirational file: https://github.com/python/cpython/blob/master/Python/symtabl
*/
use crate::error::{CompileError, CompileErrorType};
use indexmap::map::IndexMap;
use crate::IndexMap;
use rustpython_ast::{self as ast, Location};
use std::fmt;
@@ -58,7 +58,7 @@ impl SymbolTable {
typ,
line_number,
is_nested,
symbols: IndexMap::new(),
symbols: IndexMap::default(),
sub_tables: vec![],
}
}

View File

@@ -20,3 +20,6 @@ num-traits = "0.2"
unic-emoji-char = "0.9"
unic-ucd-ident = "0.9"
unicode_names2 = "0.4"
phf = { version = "0.8", features = ["macros"] }
hashbrown = "0.9"
ahash = "0.6"

View File

@@ -1,3 +1,4 @@
use ahash::RandomState;
use std::collections::HashSet;
use crate::ast;
@@ -45,7 +46,7 @@ pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ast::ArgumentList,
let mut args = vec![];
let mut keywords = vec![];
let mut keyword_names = HashSet::with_capacity(func_args.len());
let mut keyword_names = HashSet::with_capacity_and_hasher(func_args.len(), RandomState::new());
for (name, value) in func_args {
match name {
Some(n) => {

View File

@@ -10,7 +10,6 @@ use num_traits::identities::Zero;
use num_traits::Num;
use std::char;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::str::FromStr;
use unic_emoji_char::is_emoji_presentation;
use unic_ucd_ident::{is_xid_continue, is_xid_start};
@@ -66,52 +65,48 @@ pub struct Lexer<T: Iterator<Item = char>> {
chr1: Option<char>,
chr2: Option<char>,
location: Location,
keywords: HashMap<String, Tok>,
}
pub fn get_keywords() -> HashMap<String, Tok> {
let mut keywords: HashMap<String, Tok> = HashMap::new();
pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! {
// Alphabetical keywords:
keywords.insert(String::from("..."), Tok::Ellipsis);
keywords.insert(String::from("False"), Tok::False);
keywords.insert(String::from("None"), Tok::None);
keywords.insert(String::from("True"), Tok::True);
"..." => Tok::Ellipsis,
"False" => Tok::False,
"None" => Tok::None,
"True" => Tok::True,
keywords.insert(String::from("and"), Tok::And);
keywords.insert(String::from("as"), Tok::As);
keywords.insert(String::from("assert"), Tok::Assert);
keywords.insert(String::from("async"), Tok::Async);
keywords.insert(String::from("await"), Tok::Await);
keywords.insert(String::from("break"), Tok::Break);
keywords.insert(String::from("class"), Tok::Class);
keywords.insert(String::from("continue"), Tok::Continue);
keywords.insert(String::from("def"), Tok::Def);
keywords.insert(String::from("del"), Tok::Del);
keywords.insert(String::from("elif"), Tok::Elif);
keywords.insert(String::from("else"), Tok::Else);
keywords.insert(String::from("except"), Tok::Except);
keywords.insert(String::from("finally"), Tok::Finally);
keywords.insert(String::from("for"), Tok::For);
keywords.insert(String::from("from"), Tok::From);
keywords.insert(String::from("global"), Tok::Global);
keywords.insert(String::from("if"), Tok::If);
keywords.insert(String::from("import"), Tok::Import);
keywords.insert(String::from("in"), Tok::In);
keywords.insert(String::from("is"), Tok::Is);
keywords.insert(String::from("lambda"), Tok::Lambda);
keywords.insert(String::from("nonlocal"), Tok::Nonlocal);
keywords.insert(String::from("not"), Tok::Not);
keywords.insert(String::from("or"), Tok::Or);
keywords.insert(String::from("pass"), Tok::Pass);
keywords.insert(String::from("raise"), Tok::Raise);
keywords.insert(String::from("return"), Tok::Return);
keywords.insert(String::from("try"), Tok::Try);
keywords.insert(String::from("while"), Tok::While);
keywords.insert(String::from("with"), Tok::With);
keywords.insert(String::from("yield"), Tok::Yield);
keywords
}
"and" => Tok::And,
"as" => Tok::As,
"assert" => Tok::Assert,
"async" => Tok::Async,
"await" => Tok::Await,
"break" => Tok::Break,
"class" => Tok::Class,
"continue" => Tok::Continue,
"def" => Tok::Def,
"del" => Tok::Del,
"elif" => Tok::Elif,
"else" => Tok::Else,
"except" => Tok::Except,
"finally" => Tok::Finally,
"for" => Tok::For,
"from" => Tok::From,
"global" => Tok::Global,
"if" => Tok::If,
"import" => Tok::Import,
"in" => Tok::In,
"is" => Tok::Is,
"lambda" => Tok::Lambda,
"nonlocal" => Tok::Nonlocal,
"not" => Tok::Not,
"or" => Tok::Or,
"pass" => Tok::Pass,
"raise" => Tok::Raise,
"return" => Tok::Return,
"try" => Tok::Try,
"while" => Tok::While,
"with" => Tok::With,
"yield" => Tok::Yield,
};
pub type Spanned = (Location, Tok, Location);
pub type LexResult = Result<Spanned, LexicalError>;
@@ -193,7 +188,6 @@ where
location: Location::new(0, 0),
chr1: None,
chr2: None,
keywords: get_keywords(),
};
lxr.next_char();
lxr.next_char();
@@ -245,8 +239,8 @@ where
}
let end_pos = self.get_pos();
if self.keywords.contains_key(&name) {
Ok((start_pos, self.keywords[&name].clone(), end_pos))
if let Some(tok) = KEYWORDS.get(name.as_str()) {
Ok((start_pos, tok.clone(), end_pos))
} else {
Ok((start_pos, Tok::Name { name }, end_pos))
}

View File

@@ -57,8 +57,8 @@ itertools = "0.9"
hex = "0.4.0"
hexf-parse = "0.1.0"
indexmap = "1.0.2"
ahash = "0.6"
crc = "^1.0.0"
maplit = "1.0"
bitflags = "1.2.1"
libc = "0.2"
nix = "0.18"

View File

@@ -450,7 +450,7 @@ impl PyDictRef {
/// Take a python dictionary and convert it to attributes.
pub fn to_attributes(self) -> PyAttributes {
let mut attrs = PyAttributes::new();
let mut attrs = PyAttributes::default();
for (key, value) in self {
let key = pystr::clone_value(&key);
attrs.insert(key, value);

View File

@@ -908,7 +908,7 @@ pub(crate) fn try_int(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<BigInt
vm.to_repr(obj)?,
))),
}
};
}
// test for strings and bytes
if let Some(s) = obj.downcast_ref::<PyStr>() {

View File

@@ -2,7 +2,7 @@ use crate::common::lock::{
PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard,
PyRwLockWriteGuard,
};
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use std::fmt;
use super::classmethod::PyClassMethod;
@@ -133,7 +133,7 @@ impl PyType {
pub fn get_attributes(&self) -> PyAttributes {
// Gather all members here:
let mut attributes = PyAttributes::new();
let mut attributes = PyAttributes::default();
for bc in self.iter_mro().rev() {
for (name, value) in bc.attributes.read().iter() {
@@ -791,7 +791,7 @@ pub fn new(
name: &str,
base: PyTypeRef,
bases: Vec<PyTypeRef>,
attrs: HashMap<String, PyObjectRef>,
attrs: PyAttributes,
mut slots: PyTypeSlots,
) -> Result<PyTypeRef, String> {
// Check for duplicates in bases.
@@ -914,8 +914,7 @@ fn best_base(bases: &[PyTypeRef], vm: &VirtualMachine) -> PyResult<PyTypeRef> {
#[cfg(test)]
mod tests {
use super::{linearise_mro, new};
use super::{HashMap, IdProtocol, PyContext, PyTypeRef};
use super::*;
fn map_ids(obj: Result<Vec<PyTypeRef>, String>) -> Result<Vec<usize>, String> {
Ok(obj?.into_iter().map(|x| x.get_id()).collect())
@@ -932,7 +931,7 @@ mod tests {
"A",
object.clone(),
vec![object.clone()],
HashMap::new(),
PyAttributes::default(),
Default::default(),
)
.unwrap();
@@ -941,7 +940,7 @@ mod tests {
"B",
object.clone(),
vec![object.clone()],
HashMap::new(),
PyAttributes::default(),
Default::default(),
)
.unwrap();

View File

@@ -19,8 +19,10 @@ pub fn map_frozen<'a>(
})
}
pub fn get_module_inits(vm: &VirtualMachine) -> HashMap<String, code::FrozenModule> {
let mut modules = HashMap::new();
pub fn get_module_inits(
vm: &VirtualMachine,
) -> HashMap<String, code::FrozenModule, ahash::RandomState> {
let mut modules = HashMap::default();
macro_rules! ext_modules {
($($t:tt)*) => {

View File

@@ -10,7 +10,6 @@ use crate::vm::VirtualMachine;
use indexmap::IndexMap;
use itertools::Itertools;
use result_like::impl_option_like;
use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::RangeInclusive;
@@ -325,9 +324,9 @@ impl<T> KwArgs<T> {
self.0.remove(name)
}
}
impl<T> From<HashMap<String, T>> for KwArgs<T> {
fn from(kwargs: HashMap<String, T>) -> Self {
KwArgs(kwargs.into_iter().collect())
impl<T> std::iter::FromIterator<(String, T)> for KwArgs<T> {
fn from_iter<I: IntoIterator<Item = (String, T)>>(iter: I) -> Self {
KwArgs(iter.into_iter().collect())
}
}
impl<T> Default for KwArgs<T> {

View File

@@ -21,8 +21,6 @@ extern crate flamer;
extern crate bitflags;
#[macro_use]
extern crate log;
#[macro_use]
extern crate maplit;
// extern crate env_logger;
#[macro_use]

View File

@@ -256,3 +256,21 @@ cfg_if::cfg_if! {
}
}
}
/// A modified version of the hashmap! macro from the maplit crate
macro_rules! hashmap {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));
(hasher=$hasher:expr, $($key:expr => $value:expr,)+) => { hashmap!(hasher=$hasher, $($key => $value),+) };
(hasher=$hasher:expr, $($key:expr => $value:expr),*) => {
{
let _cap = hashmap!(@count $($key),*);
let mut _map = ::std::collections::HashMap::with_capacity_and_hasher(_cap, $hasher);
$(
let _ = _map.insert($key, $value);
)*
_map
}
};
}

View File

@@ -64,7 +64,7 @@ pub type PyResult<T = PyObjectRef> = Result<T, PyBaseExceptionRef>; // A valid v
/// For attributes we do not use a dict, but a hashmap. This is probably
/// faster, unordered, and only supports strings as keys.
/// TODO: class attributes should maintain insertion order (use IndexMap here)
pub type PyAttributes = HashMap<String, PyObjectRef>;
pub type PyAttributes = HashMap<String, PyObjectRef, ahash::RandomState>;
// TODO: remove this impl
impl fmt::Display for PyObjectRef {

View File

@@ -489,7 +489,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef) {
bases: vec![],
mro: vec![],
subclasses: PyRwLock::default(),
attributes: PyRwLock::new(PyAttributes::new()),
attributes: PyRwLock::new(PyAttributes::default()),
slots: PyType::make_slots(),
};
let object_payload = PyType {
@@ -498,7 +498,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef) {
bases: vec![],
mro: vec![],
subclasses: PyRwLock::default(),
attributes: PyRwLock::new(PyAttributes::new()),
attributes: PyRwLock::new(PyAttributes::default()),
slots: object::PyBaseObject::make_slots(),
};
let type_type = PyRc::new(partially_init!(

View File

@@ -6,21 +6,18 @@ mod decl {
use rustpython_parser::lexer;
use crate::builtins::pystr::PyStrRef;
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult};
use crate::pyobject::{BorrowValue, PyObjectRef};
use crate::vm::VirtualMachine;
#[pyfunction]
fn iskeyword(s: PyStrRef, vm: &VirtualMachine) -> PyResult {
let keywords = lexer::get_keywords();
let value = keywords.contains_key(s.borrow_value());
let value = vm.ctx.new_bool(value);
Ok(value)
fn iskeyword(s: PyStrRef) -> bool {
lexer::KEYWORDS.contains_key(s.borrow_value())
}
#[pyattr]
fn kwlist(vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.new_list(
lexer::get_keywords()
lexer::KEYWORDS
.keys()
.map(|k| vm.ctx.new_str(k.to_owned()))
.collect(),

View File

@@ -71,9 +71,10 @@ mod zlib;
pub type StdlibInitFunc = Box<py_dyn_fn!(dyn Fn(&VirtualMachine) -> PyObjectRef)>;
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc, ahash::RandomState> {
#[allow(unused_mut)]
let mut modules = hashmap! {
hasher = ahash::RandomState::default(),
"array".to_owned() => Box::new(array::make_module) as StdlibInitFunc,
"atexit".to_owned() => Box::new(atexit::make_module),
"binascii".to_owned() => Box::new(binascii::make_module),

View File

@@ -4,7 +4,7 @@ use crate::builtins::pytype::PyTypeRef;
use crate::builtins::tuple::PyTupleRef;
/// Implementation of the _thread module
use crate::exceptions::{self, IntoPyException};
use crate::function::{FuncArgs, OptionalArg};
use crate::function::{FuncArgs, KwArgs, OptionalArg};
use crate::pyobject::{
BorrowValue, Either, IdProtocol, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef,
PyResult, PyValue, StaticType, TypeProtocol,
@@ -224,7 +224,10 @@ fn _thread_start_new_thread(
) -> PyResult<u64> {
let args = FuncArgs::new(
args.borrow_value().to_owned(),
kwargs.map_or_else(Default::default, |k| k.to_attributes()),
kwargs
.map_or_else(Default::default, |k| k.to_attributes())
.into_iter()
.collect::<KwArgs>(),
);
let mut thread_builder = thread::Builder::new();
let stacksize = vm.state.stacksize.load();

View File

@@ -255,7 +255,7 @@ pub fn create_type_with_slots(
base: &PyTypeRef,
slots: PyTypeSlots,
) -> PyTypeRef {
let dict = PyAttributes::new();
let dict = PyAttributes::default();
pytype::new(
type_type.clone(),
name,

View File

@@ -5,8 +5,8 @@
//!
use std::cell::{Cell, Ref, RefCell};
use std::collections::hash_map::HashMap;
use std::collections::hash_set::HashSet;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt;
use crossbeam_utils::atomic::AtomicCell;
@@ -110,8 +110,8 @@ pub(crate) mod thread {
pub struct PyGlobalState {
pub settings: PySettings,
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc>,
pub frozen: HashMap<String, code::FrozenModule>,
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc, ahash::RandomState>,
pub frozen: HashMap<String, code::FrozenModule, ahash::RandomState>,
pub stacksize: AtomicCell<usize>,
pub thread_count: AtomicCell<usize>,
pub hash_secret: HashSecret,
@@ -273,7 +273,7 @@ impl VirtualMachine {
state: PyRc::new(PyGlobalState {
settings,
stdlib_inits,
frozen: HashMap::new(),
frozen: HashMap::default(),
stacksize: AtomicCell::new(0),
thread_count: AtomicCell::new(0),
hash_secret,