2
2
3
3
import java .lang .reflect .Method ;
4
4
import java .lang .reflect .Modifier ;
5
- import java .util .Collections ;
6
5
import java .util .HashSet ;
7
6
import java .util .IdentityHashMap ;
8
- import java .util .List ;
9
- import java .util .Map ;
10
7
import java .util .Set ;
11
8
9
+ import ai .timefold .jpyinterpreter .implementors .DelegatingInterfaceImplementor ;
12
10
import ai .timefold .jpyinterpreter .implementors .JavaPythonTypeConversionImplementor ;
13
11
import ai .timefold .jpyinterpreter .types .BuiltinTypes ;
14
12
import ai .timefold .jpyinterpreter .types .PythonLikeType ;
15
13
import ai .timefold .jpyinterpreter .util .MethodVisitorAdapters ;
16
14
import ai .timefold .jpyinterpreter .util .arguments .ArgumentSpec ;
17
15
18
16
import org .objectweb .asm .ClassWriter ;
19
- import org .objectweb .asm .MethodVisitor ;
20
17
import org .objectweb .asm .Opcodes ;
21
18
import org .objectweb .asm .Type ;
22
19
@@ -251,64 +248,26 @@ private static void createMethodDelegate(ClassWriter classWriter,
251
248
interfaceMethodVisitor .visitFieldInsn (Opcodes .GETSTATIC , wrapperInternalName ,
252
249
"argumentSpec$" + interfaceMethod .getName (),
253
250
Type .getDescriptor (ArgumentSpec .class ));
254
- interfaceMethodVisitor .visitLdcInsn (interfaceMethod .getParameterCount ());
255
- interfaceMethodVisitor .visitTypeInsn (Opcodes .ANEWARRAY , Type .getInternalName (PythonLikeObject .class ));
256
- interfaceMethodVisitor .visitVarInsn (Opcodes .ASTORE , interfaceMethod .getParameterCount () + 2 );
257
- for (int i = 0 ; i < interfaceMethod .getParameterCount (); i ++) {
258
- var parameterType = interfaceMethod .getParameterTypes ()[i ];
259
- interfaceMethodVisitor .visitVarInsn (Opcodes .ALOAD , interfaceMethod .getParameterCount () + 2 );
260
- interfaceMethodVisitor .visitLdcInsn (i );
261
- interfaceMethodVisitor .visitVarInsn (Type .getType (parameterType ).getOpcode (Opcodes .ILOAD ),
262
- i + 1 );
263
- if (parameterType .isPrimitive ()) {
264
- convertPrimitiveToObjectType (parameterType , interfaceMethodVisitor );
265
- }
266
- interfaceMethodVisitor .visitVarInsn (Opcodes .ALOAD , interfaceMethod .getParameterCount () + 1 );
267
- interfaceMethodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC ,
268
- Type .getInternalName (JavaPythonTypeConversionImplementor .class ),
269
- "wrapJavaObject" ,
270
- Type .getMethodDescriptor (Type .getType (PythonLikeObject .class ), Type .getType (Object .class ), Type .getType (
271
- Map .class )),
272
- false );
273
- interfaceMethodVisitor .visitInsn (Opcodes .AASTORE );
274
- }
275
251
276
252
var functionSignature = delegateType .getMethodType (interfaceMethod .getName ())
277
253
.orElseThrow (() -> new IllegalArgumentException (
278
254
"Type %s cannot implement interface %s because it missing method %s."
279
255
.formatted (delegateType , interfaceMethod .getDeclaringClass (), interfaceMethod )))
280
256
.getDefaultFunctionSignature ()
281
257
.orElseThrow ();
282
-
283
- interfaceMethodVisitor .visitVarInsn (Opcodes .ALOAD , interfaceMethod .getParameterCount () + 2 );
284
- interfaceMethodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (List .class ),
285
- "of" , Type .getMethodDescriptor (Type .getType (List .class ), Type .getType (Object [].class )),
286
- true );
287
- interfaceMethodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Collections .class ),
288
- "emptyMap" , Type .getMethodDescriptor (Type .getType (Map .class )), false );
289
- interfaceMethodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (ArgumentSpec .class ),
290
- "extractArgumentList" , Type .getMethodDescriptor (
291
- Type .getType (List .class ), Type .getType (List .class ), Type .getType (Map .class )),
258
+ DelegatingInterfaceImplementor .prepareParametersForMethodCallFromArgumentSpec (
259
+ interfaceMethod , interfaceMethodVisitor , functionSignature .getParameterTypes ().length ,
260
+ Type .getType (functionSignature .getMethodDescriptor ().getMethodDescriptor ()),
292
261
false );
293
262
294
- for (int i = 0 ; i < functionSignature .getParameterTypes ().length ; i ++) {
295
- interfaceMethodVisitor .visitInsn (Opcodes .DUP );
296
- interfaceMethodVisitor .visitLdcInsn (i );
297
- interfaceMethodVisitor .visitMethodInsn (Opcodes .INVOKEINTERFACE , Type .getInternalName (List .class ),
298
- "get" , Type .getMethodDescriptor (Type .getType (Object .class ), Type .INT_TYPE ), true );
299
- interfaceMethodVisitor .visitTypeInsn (Opcodes .CHECKCAST ,
300
- functionSignature .getParameterTypes ()[i ].getJavaTypeInternalName ());
301
- interfaceMethodVisitor .visitInsn (Opcodes .SWAP );
302
- }
303
- interfaceMethodVisitor .visitInsn (Opcodes .POP );
304
263
functionSignature .getMethodDescriptor ().callMethod (interfaceMethodVisitor );
305
264
306
265
var returnType = interfaceMethod .getReturnType ();
307
266
if (returnType .equals (void .class )) {
308
267
interfaceMethodVisitor .visitInsn (Opcodes .RETURN );
309
268
} else {
310
269
if (returnType .isPrimitive ()) {
311
- loadBoxedPrimitiveTypeClass (returnType , interfaceMethodVisitor );
270
+ DelegatingInterfaceImplementor . loadBoxedPrimitiveTypeClass (returnType , interfaceMethodVisitor );
312
271
} else {
313
272
interfaceMethodVisitor .visitLdcInsn (Type .getType (returnType ));
314
273
}
@@ -320,7 +279,7 @@ private static void createMethodDelegate(ClassWriter classWriter,
320
279
PythonLikeObject .class )),
321
280
false );
322
281
if (returnType .isPrimitive ()) {
323
- unboxBoxedPrimitiveType (returnType , interfaceMethodVisitor );
282
+ DelegatingInterfaceImplementor . unboxBoxedPrimitiveType (returnType , interfaceMethodVisitor );
324
283
interfaceMethodVisitor .visitInsn (Type .getType (returnType ).getOpcode (Opcodes .IRETURN ));
325
284
} else {
326
285
interfaceMethodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (returnType ));
@@ -330,94 +289,4 @@ private static void createMethodDelegate(ClassWriter classWriter,
330
289
interfaceMethodVisitor .visitMaxs (interfaceMethod .getParameterCount () + 2 , 1 );
331
290
interfaceMethodVisitor .visitEnd ();
332
291
}
333
-
334
- private static void convertPrimitiveToObjectType (Class <?> primitiveType , MethodVisitor methodVisitor ) {
335
- if (primitiveType .equals (boolean .class )) {
336
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Boolean .class ),
337
- "valueOf" , Type .getMethodDescriptor (Type .getType (Boolean .class ), Type .BOOLEAN_TYPE ), false );
338
- } else if (primitiveType .equals (byte .class )) {
339
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Byte .class ),
340
- "valueOf" , Type .getMethodDescriptor (Type .getType (Byte .class ), Type .BYTE_TYPE ), false );
341
- } else if (primitiveType .equals (char .class )) {
342
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Character .class ),
343
- "valueOf" , Type .getMethodDescriptor (Type .getType (Character .class ), Type .CHAR_TYPE ), false );
344
- } else if (primitiveType .equals (short .class )) {
345
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Short .class ),
346
- "valueOf" , Type .getMethodDescriptor (Type .getType (Short .class ), Type .SHORT_TYPE ), false );
347
- } else if (primitiveType .equals (int .class )) {
348
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Integer .class ),
349
- "valueOf" , Type .getMethodDescriptor (Type .getType (Integer .class ), Type .INT_TYPE ), false );
350
- } else if (primitiveType .equals (long .class )) {
351
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Long .class ),
352
- "valueOf" , Type .getMethodDescriptor (Type .getType (Long .class ), Type .LONG_TYPE ), false );
353
- } else if (primitiveType .equals (float .class )) {
354
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Float .class ),
355
- "valueOf" , Type .getMethodDescriptor (Type .getType (Float .class ), Type .FLOAT_TYPE ), false );
356
- } else if (primitiveType .equals (double .class )) {
357
- methodVisitor .visitMethodInsn (Opcodes .INVOKESTATIC , Type .getInternalName (Double .class ),
358
- "valueOf" , Type .getMethodDescriptor (Type .getType (Double .class ), Type .DOUBLE_TYPE ), false );
359
- } else {
360
- throw new IllegalStateException ("Unknown primitive type %s." .formatted (primitiveType ));
361
- }
362
- }
363
-
364
- private static void loadBoxedPrimitiveTypeClass (Class <?> primitiveType , MethodVisitor methodVisitor ) {
365
- if (primitiveType .equals (boolean .class )) {
366
- methodVisitor .visitLdcInsn (Type .getType (Boolean .class ));
367
- } else if (primitiveType .equals (byte .class )) {
368
- methodVisitor .visitLdcInsn (Type .getType (Byte .class ));
369
- } else if (primitiveType .equals (char .class )) {
370
- methodVisitor .visitLdcInsn (Type .getType (Character .class ));
371
- } else if (primitiveType .equals (short .class )) {
372
- methodVisitor .visitLdcInsn (Type .getType (Short .class ));
373
- } else if (primitiveType .equals (int .class )) {
374
- methodVisitor .visitLdcInsn (Type .getType (Integer .class ));
375
- } else if (primitiveType .equals (long .class )) {
376
- methodVisitor .visitLdcInsn (Type .getType (Long .class ));
377
- } else if (primitiveType .equals (float .class )) {
378
- methodVisitor .visitLdcInsn (Type .getType (Float .class ));
379
- } else if (primitiveType .equals (double .class )) {
380
- methodVisitor .visitLdcInsn (Type .getType (Double .class ));
381
- } else {
382
- throw new IllegalStateException ("Unknown primitive type %s." .formatted (primitiveType ));
383
- }
384
- }
385
-
386
- private static void unboxBoxedPrimitiveType (Class <?> primitiveType , MethodVisitor methodVisitor ) {
387
- if (primitiveType .equals (boolean .class )) {
388
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Boolean .class ));
389
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Boolean .class ),
390
- "booleanValue" , Type .getMethodDescriptor (Type .BOOLEAN_TYPE ), false );
391
- } else if (primitiveType .equals (byte .class )) {
392
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Byte .class ));
393
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Byte .class ),
394
- "byteValue" , Type .getMethodDescriptor (Type .BYTE_TYPE ), false );
395
- } else if (primitiveType .equals (char .class )) {
396
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Character .class ));
397
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Character .class ),
398
- "charValue" , Type .getMethodDescriptor (Type .CHAR_TYPE ), false );
399
- } else if (primitiveType .equals (short .class )) {
400
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Short .class ));
401
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Short .class ),
402
- "shortValue" , Type .getMethodDescriptor (Type .SHORT_TYPE ), false );
403
- } else if (primitiveType .equals (int .class )) {
404
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Integer .class ));
405
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Integer .class ),
406
- "intValue" , Type .getMethodDescriptor (Type .INT_TYPE ), false );
407
- } else if (primitiveType .equals (long .class )) {
408
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Long .class ));
409
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Long .class ),
410
- "longValue" , Type .getMethodDescriptor (Type .LONG_TYPE ), false );
411
- } else if (primitiveType .equals (float .class )) {
412
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Float .class ));
413
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Float .class ),
414
- "floatValue" , Type .getMethodDescriptor (Type .FLOAT_TYPE ), false );
415
- } else if (primitiveType .equals (double .class )) {
416
- methodVisitor .visitTypeInsn (Opcodes .CHECKCAST , Type .getInternalName (Double .class ));
417
- methodVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , Type .getInternalName (Double .class ),
418
- "doubleValue" , Type .getMethodDescriptor (Type .DOUBLE_TYPE ), false );
419
- } else {
420
- throw new IllegalStateException ("Unknown primitive type %s." .formatted (primitiveType ));
421
- }
422
- }
423
292
}
0 commit comments