@@ -8,7 +8,6 @@ use crate::{
8
8
VirtualMachine ,
9
9
} ;
10
10
use crossbeam_utils:: atomic:: AtomicCell ;
11
- use std:: ptr;
12
11
13
12
type UnaryFunc < R = PyObjectRef > = AtomicCell < Option < fn ( PyNumber , & VirtualMachine ) -> PyResult < R > > > ;
14
13
type BinaryFunc < R = PyObjectRef > =
@@ -110,7 +109,6 @@ impl PyObject {
110
109
}
111
110
112
111
#[ derive( Default ) ]
113
- // #[repr(C)]
114
112
pub struct PyNumberMethods {
115
113
/* Number implementations must check *both*
116
114
arguments for proper type and implement the necessary conversions
@@ -138,7 +136,6 @@ pub struct PyNumberMethods {
138
136
pub inplace_subtract : BinaryFunc ,
139
137
pub inplace_multiply : BinaryFunc ,
140
138
pub inplace_remainder : BinaryFunc ,
141
- pub inplace_divmod : BinaryFunc ,
142
139
pub inplace_power : BinaryFunc ,
143
140
pub inplace_lshift : BinaryFunc ,
144
141
pub inplace_rshift : BinaryFunc ,
@@ -184,7 +181,6 @@ impl PyNumberMethods {
184
181
inplace_subtract : AtomicCell :: new ( None ) ,
185
182
inplace_multiply : AtomicCell :: new ( None ) ,
186
183
inplace_remainder : AtomicCell :: new ( None ) ,
187
- inplace_divmod : AtomicCell :: new ( None ) ,
188
184
inplace_power : AtomicCell :: new ( None ) ,
189
185
inplace_lshift : AtomicCell :: new ( None ) ,
190
186
inplace_rshift : AtomicCell :: new ( None ) ,
@@ -199,32 +195,58 @@ impl PyNumberMethods {
199
195
matrix_multiply : AtomicCell :: new ( None ) ,
200
196
inplace_matrix_multiply : AtomicCell :: new ( None ) ,
201
197
} ;
198
+
199
+ pub fn get_binary_op ( & self , op_slot : & PyNumberBinaryOpSlot ) -> PyResult < & BinaryFunc > {
200
+ use PyNumberBinaryOpSlot :: * ;
201
+ let binary_op = match op_slot {
202
+ Add => & self . add ,
203
+ Subtract => & self . subtract ,
204
+ Multiply => & self . multiply ,
205
+ Remainder => & self . remainder ,
206
+ Divmod => & self . divmod ,
207
+ Power => & self . power ,
208
+ Lshift => & self . lshift ,
209
+ Rshift => & self . rshift ,
210
+ And => & self . and ,
211
+ Xor => & self . xor ,
212
+ Or => & self . or ,
213
+ InplaceAdd => & self . inplace_add ,
214
+ InplaceSubtract => & self . inplace_subtract ,
215
+ InplaceMultiply => & self . inplace_multiply ,
216
+ InplaceRemainder => & self . inplace_remainder ,
217
+ InplacePower => & self . inplace_power ,
218
+ InplaceLshift => & self . inplace_lshift ,
219
+ InplaceRshift => & self . inplace_rshift ,
220
+ InplaceAnd => & self . inplace_and ,
221
+ InplaceXor => & self . inplace_xor ,
222
+ InplaceOr => & self . inplace_or ,
223
+ FloorDivide => & self . floor_divide ,
224
+ TrueDivide => & self . true_divide ,
225
+ InplaceFloorDivide => & self . inplace_floor_divide ,
226
+ InplaceTrueDivide => & self . inplace_true_divide ,
227
+ MatrixMultiply => & self . matrix_multiply ,
228
+ InplaceMatrixMultiply => & self . inplace_matrix_multiply ,
229
+ } ;
230
+ Ok ( binary_op)
231
+ }
202
232
}
203
233
204
- pub enum PyNumberMethodsOffset {
234
+ pub enum PyNumberBinaryOpSlot {
205
235
Add ,
206
236
Subtract ,
207
237
Multiply ,
208
238
Remainder ,
209
239
Divmod ,
210
240
Power ,
211
- Negative ,
212
- Positive ,
213
- Absolute ,
214
- Boolean ,
215
- Invert ,
216
241
Lshift ,
217
242
Rshift ,
218
243
And ,
219
244
Xor ,
220
245
Or ,
221
- Int ,
222
- Float ,
223
246
InplaceAdd ,
224
247
InplaceSubtract ,
225
248
InplaceMultiply ,
226
249
InplaceRemainder ,
227
- InplaceDivmod ,
228
250
InplacePower ,
229
251
InplaceLshift ,
230
252
InplaceRshift ,
@@ -235,63 +257,10 @@ pub enum PyNumberMethodsOffset {
235
257
TrueDivide ,
236
258
InplaceFloorDivide ,
237
259
InplaceTrueDivide ,
238
- Index ,
239
260
MatrixMultiply ,
240
261
InplaceMatrixMultiply ,
241
262
}
242
263
243
- impl PyNumberMethodsOffset {
244
- pub fn method ( & self , methods : & PyNumberMethods , vm : & VirtualMachine ) -> PyResult < & BinaryFunc > {
245
- use PyNumberMethodsOffset :: * ;
246
- unsafe {
247
- match self {
248
- // BinaryFunc
249
- Add => ptr:: addr_of!( methods. add) ,
250
- Subtract => ptr:: addr_of!( methods. subtract) ,
251
- Multiply => ptr:: addr_of!( methods. multiply) ,
252
- Remainder => ptr:: addr_of!( methods. remainder) ,
253
- Divmod => ptr:: addr_of!( methods. divmod) ,
254
- Power => ptr:: addr_of!( methods. power) ,
255
- Lshift => ptr:: addr_of!( methods. lshift) ,
256
- Rshift => ptr:: addr_of!( methods. rshift) ,
257
- And => ptr:: addr_of!( methods. and) ,
258
- Xor => ptr:: addr_of!( methods. xor) ,
259
- Or => ptr:: addr_of!( methods. or) ,
260
- InplaceAdd => ptr:: addr_of!( methods. inplace_add) ,
261
- InplaceSubtract => ptr:: addr_of!( methods. inplace_subtract) ,
262
- InplaceMultiply => ptr:: addr_of!( methods. inplace_multiply) ,
263
- InplaceRemainder => ptr:: addr_of!( methods. inplace_remainder) ,
264
- InplaceDivmod => ptr:: addr_of!( methods. inplace_divmod) ,
265
- InplacePower => ptr:: addr_of!( methods. inplace_power) ,
266
- InplaceLshift => ptr:: addr_of!( methods. inplace_lshift) ,
267
- InplaceRshift => ptr:: addr_of!( methods. inplace_rshift) ,
268
- InplaceAnd => ptr:: addr_of!( methods. inplace_and) ,
269
- InplaceXor => ptr:: addr_of!( methods. inplace_xor) ,
270
- InplaceOr => ptr:: addr_of!( methods. inplace_or) ,
271
- FloorDivide => ptr:: addr_of!( methods. floor_divide) ,
272
- TrueDivide => ptr:: addr_of!( methods. true_divide) ,
273
- InplaceFloorDivide => ptr:: addr_of!( methods. inplace_floor_divide) ,
274
- InplaceTrueDivide => ptr:: addr_of!( methods. inplace_true_divide) ,
275
- MatrixMultiply => ptr:: addr_of!( methods. matrix_multiply) ,
276
- InplaceMatrixMultiply => ptr:: addr_of!( methods. inplace_matrix_multiply) ,
277
- // UnaryFunc
278
- Negative => ptr:: null ( ) ,
279
- Positive => ptr:: null ( ) ,
280
- Absolute => ptr:: null ( ) ,
281
- Boolean => ptr:: null ( ) ,
282
- Invert => ptr:: null ( ) ,
283
- Int => ptr:: null ( ) ,
284
- Float => ptr:: null ( ) ,
285
- Index => ptr:: null ( ) ,
286
- }
287
- . as_ref ( )
288
- . ok_or_else ( || {
289
- vm. new_value_error ( "No unaryop supported for PyNumberMethodsOffset" . to_owned ( ) )
290
- } )
291
- }
292
- }
293
- }
294
-
295
264
#[ derive( Copy , Clone ) ]
296
265
pub struct PyNumber < ' a > {
297
266
pub obj : & ' a PyObject ,
@@ -314,12 +283,12 @@ impl PyNumber<'_> {
314
283
obj. class ( ) . mro_find_map ( |x| x. slots . as_number . load ( ) )
315
284
}
316
285
317
- pub fn methods < ' a > (
318
- & ' a self ,
319
- op_slot : & ' a PyNumberMethodsOffset ,
320
- vm : & VirtualMachine ,
321
- ) -> PyResult < & BinaryFunc > {
322
- op_slot . method ( self . methods , vm )
286
+ pub fn methods ( & self ) -> & PyNumberMethods {
287
+ self . methods
288
+ }
289
+
290
+ pub fn get_binary_op ( & self , op_slot : & PyNumberBinaryOpSlot ) -> PyResult < & BinaryFunc > {
291
+ self . methods ( ) . get_binary_op ( op_slot )
323
292
}
324
293
325
294
// PyNumber_Check
@@ -336,12 +305,12 @@ impl PyNumber<'_> {
336
305
337
306
// PyIndex_Check
338
307
pub fn is_index ( & self ) -> bool {
339
- self . methods . index . load ( ) . is_some ( )
308
+ self . methods ( ) . index . load ( ) . is_some ( )
340
309
}
341
310
342
311
#[ inline]
343
312
pub fn int ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
344
- self . methods . int . load ( ) . map ( |f| {
313
+ self . methods ( ) . int . load ( ) . map ( |f| {
345
314
let ret = f ( self , vm) ?;
346
315
let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
347
316
warnings:: warn (
@@ -365,7 +334,7 @@ impl PyNumber<'_> {
365
334
366
335
#[ inline]
367
336
pub fn index ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
368
- self . methods . index . load ( ) . map ( |f| {
337
+ self . methods ( ) . index . load ( ) . map ( |f| {
369
338
let ret = f ( self , vm) ?;
370
339
let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
371
340
warnings:: warn (
@@ -389,7 +358,7 @@ impl PyNumber<'_> {
389
358
390
359
#[ inline]
391
360
pub fn float ( self , vm : & VirtualMachine ) -> Option < PyResult < PyRef < PyFloat > > > {
392
- self . methods . float . load ( ) . map ( |f| {
361
+ self . methods ( ) . float . load ( ) . map ( |f| {
393
362
let ret = f ( self , vm) ?;
394
363
let value = if !ret. class ( ) . is ( PyFloat :: class ( vm) ) {
395
364
warnings:: warn (
0 commit comments