Skip to content

Commit c44843f

Browse files
authored
Merge pull request RustPython#3700 from youknowone/attr-intern
PyStrInterned for PyAttributes/Constants
2 parents 51175fe + 14e4aee commit c44843f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1740
-1051
lines changed

ast/asdl_rs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,9 @@ def gen_classdef(self, name, fields, attrs, depth, base="AstNode"):
389389
self.emit(f"#[extend_class]", depth + 1)
390390
self.emit("fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) {", depth + 1)
391391
fields = ",".join(f"ctx.new_str(ascii!({json.dumps(f.name)})).into()" for f in fields)
392-
self.emit(f'class.set_str_attr("_fields", ctx.new_list(vec![{fields}]));', depth + 2)
392+
self.emit(f'class.set_attr(interned!(ctx, _fields), ctx.new_list(vec![{fields}]).into());', depth + 2)
393393
attrs = ",".join(f"ctx.new_str(ascii!({json.dumps(attr.name)})).into()" for attr in attrs)
394-
self.emit(f'class.set_str_attr("_attributes", ctx.new_list(vec![{attrs}]));', depth + 2)
394+
self.emit(f'class.set_attr(interned!(ctx, _attributes), ctx.new_list(vec![{attrs}]).into());', depth + 2)
395395
self.emit("}", depth + 1)
396396
self.emit("}", depth)
397397

benches/execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
116116
.map(|entry| {
117117
let path = entry.unwrap().path();
118118
(
119-
path.file_name().unwrap().to_str().unwrap().to_owned(),
119+
path.file_name().unwrap().to_owned().unwrap().to_owned(),
120120
std::fs::read_to_string(path).unwrap(),
121121
)
122122
})

common/src/hash.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ impl HashSecret {
5454
pub fn new(seed: u32) -> Self {
5555
let mut buf = [0u8; 16];
5656
lcg_urandom(seed, &mut buf);
57-
let k0 = u64::from_le_bytes(buf[..8].try_into().unwrap());
58-
let k1 = u64::from_le_bytes(buf[8..].try_into().unwrap());
57+
let (left, right) = buf.split_at(8);
58+
let k0 = u64::from_le_bytes(left.try_into().unwrap());
59+
let k1 = u64::from_le_bytes(right.try_into().unwrap());
5960
Self { k0, k1 }
6061
}
6162
}

common/src/refcount.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::atomic::{Ordering::*, PyAtomic, Radium};
55
///
66
/// Going above this limit will abort your program (although not
77
/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
8-
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
8+
const MAX_REFCOUNT: usize = isize::MAX as usize;
99

1010
pub struct RefCount {
1111
strong: PyAtomic<usize>,
@@ -18,6 +18,8 @@ impl Default for RefCount {
1818
}
1919

2020
impl RefCount {
21+
const MASK: usize = MAX_REFCOUNT;
22+
2123
pub fn new() -> Self {
2224
RefCount {
2325
strong: Radium::new(1),
@@ -33,7 +35,7 @@ impl RefCount {
3335
pub fn inc(&self) {
3436
let old_size = self.strong.fetch_add(1, Relaxed);
3537

36-
if old_size > MAX_REFCOUNT {
38+
if old_size & Self::MASK == Self::MASK {
3739
std::process::abort();
3840
}
3941
}
@@ -58,3 +60,19 @@ impl RefCount {
5860
true
5961
}
6062
}
63+
64+
impl RefCount {
65+
// move these functions out and give separated type once type range is stabilized
66+
67+
pub fn leak(&self) {
68+
debug_assert!(!self.is_leaked());
69+
const BIT_MARKER: usize = (std::isize::MAX as usize) + 1;
70+
debug_assert_eq!(BIT_MARKER.count_ones(), 1);
71+
debug_assert_eq!(BIT_MARKER.leading_zeros(), 0);
72+
self.strong.fetch_add(BIT_MARKER, Relaxed);
73+
}
74+
75+
pub fn is_leaked(&self) -> bool {
76+
(self.strong.load(Acquire) as isize) < 0
77+
}
78+
}

derive/src/pyclass.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ where
503503
#py_name,
504504
ctx.make_funcdef(#py_name, Self::#ident)
505505
#doc
506-
#build_func
506+
#build_func,
507+
ctx,
507508
);
508509
}
509510
};
@@ -611,7 +612,7 @@ where
611612
ident,
612613
py_name.clone(),
613614
quote! {
614-
class.set_str_attr(#py_name, #value);
615+
class.set_str_attr(#py_name, #value, ctx);
615616
},
616617
)
617618
} else {
@@ -736,7 +737,8 @@ impl ToTokens for GetSetNursery {
736737
::rustpython_vm::builtins::PyGetSet::new(#name.into(), class.clone())
737738
.with_get(&Self::#getter)
738739
#setter #deleter,
739-
ctx.types.getset_type.clone(), None)
740+
ctx.types.getset_type.clone(), None),
741+
ctx
740742
);
741743
}
742744
});

derive/src/pymodule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ impl ModuleItem for ClassItem {
433433
};
434434
let class_new = quote_spanned!(ident.span() =>
435435
let new_class = <#ident as ::rustpython_vm::class::PyClassImpl>::make_class(&vm.ctx);
436-
new_class.set_str_attr("__module__", vm.new_pyobj(#module_name));
436+
new_class.set_attr(rustpython_vm::identifier!(vm, __module__), vm.new_pyobj(#module_name));
437437
);
438438
(class_name, class_new)
439439
};

src/shell/helper.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use rustpython_vm::{
33
builtins::{PyDictRef, PyStrRef},
44
function::ArgIterable,
5-
PyResult, TryFromObject, VirtualMachine,
5+
identifier, PyResult, TryFromObject, VirtualMachine,
66
};
77

88
pub struct ShellHelper<'vm> {
@@ -81,14 +81,19 @@ impl<'vm> ShellHelper<'vm> {
8181
current = current.get_attr(attr.as_str(), self.vm).ok()?;
8282
}
8383

84-
let current_iter = str_iter_method(current, "__dir__").ok()?;
84+
let current_iter = str_iter_method(current, identifier!(self.vm, __dir__)).ok()?;
8585

8686
(last, current_iter, None)
8787
} else {
8888
// we need to get a variable based off of globals/builtins
8989

90-
let globals = str_iter_method(self.globals.clone().into(), "keys").ok()?;
91-
let builtins = str_iter_method(self.vm.builtins.clone().into(), "__dir__").ok()?;
90+
let globals =
91+
str_iter_method(self.globals.clone().into(), identifier!(self.vm, keys)).ok()?;
92+
let builtins = str_iter_method(
93+
self.vm.builtins.clone().into(),
94+
identifier!(self.vm, __dir__),
95+
)
96+
.ok()?;
9297
(first, globals, Some(builtins))
9398
};
9499
Some((word_start, iter1.chain(iter2.into_iter().flatten())))

stdlib/src/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ mod array {
683683
fn typecode(&self, vm: &VirtualMachine) -> PyStrRef {
684684
vm.ctx
685685
.intern_str(self.read().typecode().to_string())
686-
.to_str()
686+
.to_owned()
687687
}
688688

689689
#[pyproperty]

stdlib/src/math.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ pub(crate) use math::make_module;
33
#[pymodule]
44
mod math {
55
use crate::vm::{
6-
builtins::{try_bigint_to_f64, try_f64_to_bigint, PyFloat, PyInt, PyIntRef},
6+
builtins::{try_bigint_to_f64, try_f64_to_bigint, PyFloat, PyInt, PyIntRef, PyStrInterned},
77
function::{ArgIntoFloat, ArgIterable, Either, OptionalArg, PosArgs},
8-
AsObject, PyObject, PyObjectRef, PyRef, PyResult, VirtualMachine,
8+
identifier, AsObject, PyObject, PyObjectRef, PyRef, PyResult, VirtualMachine,
99
};
1010
use num_bigint::BigInt;
1111
use num_traits::{One, Signed, Zero};
@@ -430,25 +430,29 @@ mod math {
430430
}
431431
}
432432

433-
fn try_magic_method(func_name: &str, vm: &VirtualMachine, value: &PyObject) -> PyResult {
433+
fn try_magic_method(
434+
func_name: &'static PyStrInterned,
435+
vm: &VirtualMachine,
436+
value: &PyObject,
437+
) -> PyResult {
434438
let method = vm.get_method_or_type_error(value.to_owned(), func_name, || {
435439
format!(
436440
"type '{}' doesn't define '{}' method",
437441
value.class().name(),
438-
func_name,
442+
func_name.as_str(),
439443
)
440444
})?;
441445
vm.invoke(&method, ())
442446
}
443447

444448
#[pyfunction]
445449
fn trunc(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
446-
try_magic_method("__trunc__", vm, &x)
450+
try_magic_method(identifier!(vm, __trunc__), vm, &x)
447451
}
448452

449453
#[pyfunction]
450454
fn ceil(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
451-
let result_or_err = try_magic_method("__ceil__", vm, &x);
455+
let result_or_err = try_magic_method(identifier!(vm, __ceil__), vm, &x);
452456
if result_or_err.is_err() {
453457
if let Ok(Some(v)) = x.try_to_f64(vm) {
454458
let v = try_f64_to_bigint(v.ceil(), vm)?;
@@ -460,7 +464,7 @@ mod math {
460464

461465
#[pyfunction]
462466
fn floor(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
463-
let result_or_err = try_magic_method("__floor__", vm, &x);
467+
let result_or_err = try_magic_method(identifier!(vm, __floor__), vm, &x);
464468
if result_or_err.is_err() {
465469
if let Ok(Some(v)) = x.try_to_f64(vm) {
466470
let v = try_f64_to_bigint(v.floor(), vm)?;

stdlib/src/pyexpat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ macro_rules! create_property {
2525
move |this: &PyExpatLikeXmlParser, func: PyObjectRef| *this.$element.write() = func,
2626
);
2727

28-
$attributes.insert($name.to_owned(), attr.into());
28+
$attributes.insert($ctx.intern_str($name), attr.into());
2929
};
3030
}
3131

0 commit comments

Comments
 (0)