@@ -8,6 +8,7 @@ use crate::{
8
8
VirtualMachine ,
9
9
} ;
10
10
use crossbeam_utils:: atomic:: AtomicCell ;
11
+ use std:: ptr;
11
12
12
13
type UnaryFunc < R = PyObjectRef > = AtomicCell < Option < fn ( PyNumber , & VirtualMachine ) -> PyResult < R > > > ;
13
14
type BinaryFunc < R = PyObjectRef > =
@@ -109,6 +110,7 @@ impl PyObject {
109
110
}
110
111
111
112
#[ derive( Default ) ]
113
+ // #[repr(C)]
112
114
pub struct PyNumberMethods {
113
115
/* Number implementations must check *both*
114
116
arguments for proper type and implement the necessary conversions
@@ -199,6 +201,98 @@ impl PyNumberMethods {
199
201
} ;
200
202
}
201
203
204
+ pub enum PyNumberMethodsOffset {
205
+ Add ,
206
+ Subtract ,
207
+ Multiply ,
208
+ Remainder ,
209
+ Divmod ,
210
+ Power ,
211
+ Negative ,
212
+ Positive ,
213
+ Absolute ,
214
+ Boolean ,
215
+ Invert ,
216
+ Lshift ,
217
+ Rshift ,
218
+ And ,
219
+ Xor ,
220
+ Or ,
221
+ Int ,
222
+ Float ,
223
+ InplaceAdd ,
224
+ InplaceSubtract ,
225
+ InplaceMultiply ,
226
+ InplaceRemainder ,
227
+ InplaceDivmod ,
228
+ InplacePower ,
229
+ InplaceLshift ,
230
+ InplaceRshift ,
231
+ InplaceAnd ,
232
+ InplaceXor ,
233
+ InplaceOr ,
234
+ FloorDivide ,
235
+ TrueDivide ,
236
+ InplaceFloorDivide ,
237
+ InplaceTrueDivide ,
238
+ Index ,
239
+ MatrixMultiply ,
240
+ InplaceMatrixMultiply ,
241
+ }
242
+
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
+ #[ derive( Copy , Clone ) ]
202
296
pub struct PyNumber < ' a > {
203
297
pub obj : & ' a PyObject ,
204
298
methods : & ' a PyNumberMethods ,
@@ -220,8 +314,12 @@ impl PyNumber<'_> {
220
314
obj. class ( ) . mro_find_map ( |x| x. slots . as_number . load ( ) )
221
315
}
222
316
223
- pub fn methods ( & self ) -> & PyNumberMethods {
224
- self . methods
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)
225
323
}
226
324
227
325
// PyNumber_Check
@@ -238,12 +336,12 @@ impl PyNumber<'_> {
238
336
239
337
// PyIndex_Check
240
338
pub fn is_index ( & self ) -> bool {
241
- self . methods ( ) . index . load ( ) . is_some ( )
339
+ self . methods . index . load ( ) . is_some ( )
242
340
}
243
341
244
342
#[ inline]
245
343
pub fn int ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
246
- self . methods ( ) . int . load ( ) . map ( |f| {
344
+ self . methods . int . load ( ) . map ( |f| {
247
345
let ret = f ( self , vm) ?;
248
346
let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
249
347
warnings:: warn (
@@ -267,7 +365,7 @@ impl PyNumber<'_> {
267
365
268
366
#[ inline]
269
367
pub fn index ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
270
- self . methods ( ) . index . load ( ) . map ( |f| {
368
+ self . methods . index . load ( ) . map ( |f| {
271
369
let ret = f ( self , vm) ?;
272
370
let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
273
371
warnings:: warn (
@@ -291,7 +389,7 @@ impl PyNumber<'_> {
291
389
292
390
#[ inline]
293
391
pub fn float ( self , vm : & VirtualMachine ) -> Option < PyResult < PyRef < PyFloat > > > {
294
- self . methods ( ) . float . load ( ) . map ( |f| {
392
+ self . methods . float . load ( ) . map ( |f| {
295
393
let ret = f ( self , vm) ?;
296
394
let value = if !ret. class ( ) . is ( PyFloat :: class ( vm) ) {
297
395
warnings:: warn (
0 commit comments