Skip to content

Commit 21c8e69

Browse files
authored
Merge pull request #3758 from youknowone/relocation-statics
move generic slots to protocol module
2 parents 7182111 + a7f9767 commit 21c8e69

File tree

4 files changed

+190
-200
lines changed

4 files changed

+190
-200
lines changed

vm/src/protocol/mapping.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,79 @@ impl PyMappingMethods {
2727
fn check(&self) -> bool {
2828
self.subscript.is_some()
2929
}
30+
31+
pub(crate) fn generic(
32+
has_length: bool,
33+
has_subscript: bool,
34+
has_ass_subscript: bool,
35+
) -> &'static Self {
36+
static METHODS: &[PyMappingMethods] = &[
37+
new_generic(false, false, false),
38+
new_generic(true, false, false),
39+
new_generic(false, true, false),
40+
new_generic(true, true, false),
41+
new_generic(false, false, true),
42+
new_generic(true, false, true),
43+
new_generic(false, true, true),
44+
new_generic(true, true, true),
45+
];
46+
47+
fn length(mapping: &PyMapping, vm: &VirtualMachine) -> PyResult<usize> {
48+
crate::types::slot_length(mapping.obj, vm)
49+
}
50+
fn subscript(mapping: &PyMapping, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
51+
vm.call_special_method(
52+
mapping.obj.to_owned(),
53+
identifier!(vm, __getitem__),
54+
(needle.to_owned(),),
55+
)
56+
}
57+
fn ass_subscript(
58+
mapping: &PyMapping,
59+
needle: &PyObject,
60+
value: Option<PyObjectRef>,
61+
vm: &VirtualMachine,
62+
) -> PyResult<()> {
63+
match value {
64+
Some(value) => vm
65+
.call_special_method(
66+
mapping.obj.to_owned(),
67+
identifier!(vm, __setitem__),
68+
(needle.to_owned(), value),
69+
)
70+
.map(|_| Ok(()))?,
71+
None => vm
72+
.call_special_method(
73+
mapping.obj.to_owned(),
74+
identifier!(vm, __delitem__),
75+
(needle.to_owned(),),
76+
)
77+
.map(|_| Ok(()))?,
78+
}
79+
}
80+
81+
const fn new_generic(
82+
has_length: bool,
83+
has_subscript: bool,
84+
has_ass_subscript: bool,
85+
) -> PyMappingMethods {
86+
PyMappingMethods {
87+
length: if has_length { Some(length) } else { None },
88+
subscript: if has_subscript { Some(subscript) } else { None },
89+
ass_subscript: if has_ass_subscript {
90+
Some(ass_subscript)
91+
} else {
92+
None
93+
},
94+
}
95+
}
96+
97+
let key = (has_length as usize)
98+
| ((has_subscript as usize) << 1)
99+
| ((has_ass_subscript as usize) << 2);
100+
101+
&METHODS[key]
102+
}
30103
}
31104

32105
#[derive(Clone)]

vm/src/protocol/number.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,58 @@ impl PyNumberMethods {
9292
matrix_multiply: None,
9393
inplace_matrix_multiply: None,
9494
};
95+
96+
pub(crate) fn generic(
97+
has_int: bool,
98+
has_float: bool,
99+
has_index: bool,
100+
) -> &'static PyNumberMethods {
101+
static METHODS: &[PyNumberMethods] = &[
102+
new_generic(false, false, false),
103+
new_generic(true, false, false),
104+
new_generic(false, true, false),
105+
new_generic(true, true, false),
106+
new_generic(false, false, true),
107+
new_generic(true, false, true),
108+
new_generic(false, true, true),
109+
new_generic(true, true, true),
110+
];
111+
112+
fn int(num: &PyNumber, vm: &VirtualMachine) -> PyResult<PyRef<PyInt>> {
113+
let ret = vm.call_special_method(num.obj.to_owned(), identifier!(vm, __int__), ())?;
114+
ret.downcast::<PyInt>().map_err(|obj| {
115+
vm.new_type_error(format!("__int__ returned non-int (type {})", obj.class()))
116+
})
117+
}
118+
fn float(num: &PyNumber, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>> {
119+
let ret = vm.call_special_method(num.obj.to_owned(), identifier!(vm, __float__), ())?;
120+
ret.downcast::<PyFloat>().map_err(|obj| {
121+
vm.new_type_error(format!(
122+
"__float__ returned non-float (type {})",
123+
obj.class()
124+
))
125+
})
126+
}
127+
fn index(num: &PyNumber, vm: &VirtualMachine) -> PyResult<PyRef<PyInt>> {
128+
let ret = vm.call_special_method(num.obj.to_owned(), identifier!(vm, __index__), ())?;
129+
ret.downcast::<PyInt>().map_err(|obj| {
130+
vm.new_type_error(format!("__index__ returned non-int (type {})", obj.class()))
131+
})
132+
}
133+
134+
const fn new_generic(has_int: bool, has_float: bool, has_index: bool) -> PyNumberMethods {
135+
PyNumberMethods {
136+
int: if has_int { Some(int) } else { None },
137+
float: if has_float { Some(float) } else { None },
138+
index: if has_index { Some(index) } else { None },
139+
..PyNumberMethods::NOT_IMPLEMENTED
140+
}
141+
}
142+
143+
let key = (has_int as usize) | ((has_float as usize) << 1) | ((has_index as usize) << 2);
144+
145+
&METHODS[key]
146+
}
95147
}
96148

97149
pub struct PyNumber<'a> {

vm/src/protocol/sequence.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,58 @@ impl PySequenceMethods {
3939
pub fn check(&self) -> bool {
4040
self.item.is_some()
4141
}
42+
43+
pub(crate) fn generic(has_length: bool, has_ass_item: bool) -> &'static PySequenceMethods {
44+
static METHODS: &[PySequenceMethods] = &[
45+
new_generic(false, false),
46+
new_generic(true, false),
47+
new_generic(false, true),
48+
new_generic(true, true),
49+
];
50+
51+
fn length(seq: &PySequence, vm: &VirtualMachine) -> PyResult<usize> {
52+
crate::types::slot_length(seq.obj, vm)
53+
}
54+
fn item(seq: &PySequence, i: isize, vm: &VirtualMachine) -> PyResult {
55+
vm.call_special_method(seq.obj.to_owned(), identifier!(vm, __getitem__), (i,))
56+
}
57+
fn ass_item(
58+
seq: &PySequence,
59+
i: isize,
60+
value: Option<PyObjectRef>,
61+
vm: &VirtualMachine,
62+
) -> PyResult<()> {
63+
match value {
64+
Some(value) => vm
65+
.call_special_method(
66+
seq.obj.to_owned(),
67+
identifier!(vm, __setitem__),
68+
(i.to_pyobject(vm), value),
69+
)
70+
.map(|_| Ok(()))?,
71+
None => vm
72+
.call_special_method(
73+
seq.obj.to_owned(),
74+
identifier!(vm, __delitem__),
75+
(i.to_pyobject(vm),),
76+
)
77+
.map(|_| Ok(()))?,
78+
}
79+
}
80+
81+
const fn new_generic(has_length: bool, has_ass_item: bool) -> PySequenceMethods {
82+
PySequenceMethods {
83+
length: if has_length { Some(length) } else { None },
84+
item: Some(item),
85+
ass_item: if has_ass_item { Some(ass_item) } else { None },
86+
..PySequenceMethods::NOT_IMPLEMENTED
87+
}
88+
}
89+
90+
let key = (has_length as usize) | ((has_ass_item as usize) << 1);
91+
92+
&METHODS[key]
93+
}
4294
}
4395

4496
impl Debug for PySequenceMethods {

0 commit comments

Comments
 (0)