Skip to content

Commit 6857384

Browse files
committed
new_mapping_wrapper as static slice
1 parent 97c2d18 commit 6857384

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

vm/src/types/slot.rs

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ macro_rules! then_some_closure {
174174
};
175175
}
176176

177-
fn length_wrapper(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
178-
let ret = vm.call_special_method(obj, identifier!(vm, __len__), ())?;
177+
fn length_wrapper(obj: &PyObject, vm: &VirtualMachine) -> PyResult<usize> {
178+
let ret = vm.call_special_method(obj.to_owned(), identifier!(vm, __len__), ())?;
179179
let len = ret.payload::<PyInt>().ok_or_else(|| {
180180
vm.new_type_error(format!(
181181
"'{}' object cannot be interpreted as an integer",
@@ -192,26 +192,30 @@ fn length_wrapper(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
192192
Ok(len as usize)
193193
}
194194

195-
fn as_mapping_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyMappingMethods {
195+
const fn new_as_mapping_wrapper(
196+
has_length: bool,
197+
has_subscript: bool,
198+
has_ass_subscript: bool,
199+
) -> PyMappingMethods {
196200
PyMappingMethods {
197-
length: then_some_closure!(
198-
zelf.class().has_attr(identifier!(vm, __len__)),
199-
|mapping, vm| { length_wrapper(mapping.obj.to_owned(), vm) }
200-
),
201-
subscript: then_some_closure!(
202-
zelf.class().has_attr(identifier!(vm, __getitem__)),
203-
|mapping, needle, vm| {
201+
length: if has_length {
202+
Some(|mapping, vm| length_wrapper(&mapping.obj, vm))
203+
} else {
204+
None
205+
},
206+
subscript: if has_subscript {
207+
Some(|mapping, needle, vm| {
204208
vm.call_special_method(
205209
mapping.obj.to_owned(),
206210
identifier!(vm, __getitem__),
207211
(needle.to_owned(),),
208212
)
209-
}
210-
),
211-
ass_subscript: then_some_closure!(
212-
zelf.class().has_attr(identifier!(vm, __setitem__))
213-
| zelf.class().has_attr(identifier!(vm, __delitem__)),
214-
|mapping, needle, value, vm| match value {
213+
})
214+
} else {
215+
None
216+
},
217+
ass_subscript: if has_ass_subscript {
218+
Some(|mapping, needle, value, vm| match value {
215219
Some(value) => vm
216220
.call_special_method(
217221
mapping.obj.to_owned(),
@@ -223,12 +227,44 @@ fn as_mapping_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyMappingMethods
223227
.call_special_method(
224228
mapping.obj.to_owned(),
225229
identifier!(vm, __delitem__),
226-
(needle.to_owned(),)
230+
(needle.to_owned(),),
227231
)
228232
.map(|_| Ok(()))?,
229-
}
230-
),
233+
})
234+
} else {
235+
None
236+
},
237+
}
238+
}
239+
240+
fn as_mapping_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyMappingMethods {
241+
static MAPPING_METHODS: &[PyMappingMethods] = &[
242+
new_as_mapping_wrapper(false, false, false),
243+
new_as_mapping_wrapper(true, false, false),
244+
new_as_mapping_wrapper(false, true, false),
245+
new_as_mapping_wrapper(true, true, false),
246+
new_as_mapping_wrapper(false, false, true),
247+
new_as_mapping_wrapper(true, false, true),
248+
new_as_mapping_wrapper(false, true, true),
249+
new_as_mapping_wrapper(true, true, true),
250+
];
251+
const fn bool_int(v: bool) -> usize {
252+
if v {
253+
1
254+
} else {
255+
0
256+
}
231257
}
258+
let (has_length, has_subscript, has_ass_subscript) = (
259+
zelf.class().has_attr(identifier!(vm, __len__)),
260+
zelf.class().has_attr(identifier!(vm, __getitem__)),
261+
zelf.class().has_attr(identifier!(vm, __setitem__))
262+
| zelf.class().has_attr(identifier!(vm, __delitem__)),
263+
);
264+
let key = (bool_int(has_length) << 0)
265+
| (bool_int(has_subscript) << 1)
266+
| (bool_int(has_ass_subscript) << 2);
267+
MAPPING_METHODS[key].clone()
232268
}
233269

234270
fn as_sequence_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> Cow<'static, PySequenceMethods> {
@@ -239,7 +275,7 @@ fn as_sequence_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> Cow<'static, PyS
239275
Cow::Owned(PySequenceMethods {
240276
length: then_some_closure!(
241277
zelf.class().has_attr(identifier!(vm, __len__)),
242-
|seq, vm| { length_wrapper(seq.obj.to_owned(), vm) }
278+
|seq, vm| { length_wrapper(&seq.obj, vm) }
243279
),
244280
item: Some(|seq, i, vm| {
245281
vm.call_special_method(

0 commit comments

Comments
 (0)