1
1
use super :: objdict;
2
2
use super :: objstr;
3
+ use crate :: function:: PyRef ;
3
4
use crate :: pyobject:: {
4
5
AttributeProtocol , IdProtocol , PyAttributes , PyContext , PyFuncArgs , PyObject , PyObjectPayload ,
5
- PyObjectRef , PyResult , TypeProtocol ,
6
+ PyObjectPayload2 , PyObjectRef , PyResult , TypeProtocol ,
6
7
} ;
7
8
use crate :: vm:: VirtualMachine ;
8
9
use std:: cell:: RefCell ;
9
10
use std:: collections:: HashMap ;
10
11
12
+ #[ derive( Clone , Debug ) ]
13
+ pub struct PyClass {
14
+ pub name : String ,
15
+ pub mro : Vec < PyObjectRef > ,
16
+ }
17
+ pub type PyClassRef = PyRef < PyClass > ;
18
+
19
+ impl PyObjectPayload2 for PyClass {
20
+ fn required_type ( ctx : & PyContext ) -> PyObjectRef {
21
+ ctx. type_type ( )
22
+ }
23
+ }
24
+
11
25
/*
12
26
* The magical type type
13
27
*/
@@ -16,11 +30,13 @@ pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type:
16
30
// this is not ideal
17
31
let ptr = PyObjectRef :: into_raw ( type_type. clone ( ) ) as * mut PyObject ;
18
32
unsafe {
19
- ( * ptr) . payload = PyObjectPayload :: Class {
20
- name : String :: from ( "type" ) ,
21
- dict : RefCell :: new ( PyAttributes :: new ( ) ) ,
22
- mro : vec ! [ object_type] ,
33
+ ( * ptr) . payload = PyObjectPayload :: AnyRustValue {
34
+ value : Box :: new ( PyClass {
35
+ name : String :: from ( "type" ) ,
36
+ mro : vec ! [ object_type] ,
37
+ } ) ,
23
38
} ;
39
+ ( * ptr) . dict = Some ( RefCell :: new ( PyAttributes :: new ( ) ) ) ;
24
40
( * ptr) . typ = Some ( type_type) ;
25
41
}
26
42
}
@@ -80,13 +96,12 @@ fn type_mro(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
80
96
}
81
97
82
98
fn _mro ( cls : PyObjectRef ) -> Option < Vec < PyObjectRef > > {
83
- match cls. payload {
84
- PyObjectPayload :: Class { ref mro, .. } => {
85
- let mut mro = mro. clone ( ) ;
86
- mro. insert ( 0 , cls. clone ( ) ) ;
87
- Some ( mro)
88
- }
89
- _ => None ,
99
+ if let Some ( PyClass { ref mro, .. } ) = cls. payload :: < PyClass > ( ) {
100
+ let mut mro = mro. clone ( ) ;
101
+ mro. insert ( 0 , cls. clone ( ) ) ;
102
+ Some ( mro)
103
+ } else {
104
+ None
90
105
}
91
106
}
92
107
@@ -127,7 +142,7 @@ fn type_subclass_check(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
127
142
}
128
143
129
144
pub fn get_type_name ( typ : & PyObjectRef ) -> String {
130
- if let PyObjectPayload :: Class { name, .. } = & typ. payload {
145
+ if let Some ( PyClass { name, .. } ) = & typ. payload :: < PyClass > ( ) {
131
146
name. clone ( )
132
147
} else {
133
148
panic ! ( "Cannot get type_name of non-type type {:?}" , typ) ;
@@ -248,7 +263,7 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
248
263
let mut base_classes = _mro ( obj. clone ( ) ) . expect ( "Type get_attributes on non-type" ) ;
249
264
base_classes. reverse ( ) ;
250
265
for bc in base_classes {
251
- if let PyObjectPayload :: Class { dict, .. } = & bc. payload {
266
+ if let Some ( ref dict) = & bc. dict {
252
267
for ( name, value) in dict. borrow ( ) . iter ( ) {
253
268
attributes. insert ( name. to_string ( ) , value. clone ( ) ) ;
254
269
}
@@ -313,14 +328,17 @@ pub fn new(
313
328
) -> PyResult {
314
329
let mros = bases. into_iter ( ) . map ( |x| _mro ( x) . unwrap ( ) ) . collect ( ) ;
315
330
let mro = linearise_mro ( mros) . unwrap ( ) ;
316
- Ok ( PyObject :: new (
317
- PyObjectPayload :: Class {
318
- name : String :: from ( name) ,
319
- dict : RefCell :: new ( dict) ,
320
- mro,
331
+ Ok ( PyObject {
332
+ payload : PyObjectPayload :: AnyRustValue {
333
+ value : Box :: new ( PyClass {
334
+ name : String :: from ( name) ,
335
+ mro,
336
+ } ) ,
321
337
} ,
322
- typ,
323
- ) )
338
+ dict : Some ( RefCell :: new ( dict) ) ,
339
+ typ : Some ( typ) ,
340
+ }
341
+ . into_ref ( ) )
324
342
}
325
343
326
344
fn type_repr ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
0 commit comments