104 * strict or not. |
104 * strict or not. |
105 * </li> |
105 * </li> |
106 * <li> |
106 * <li> |
107 * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass |
107 * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass |
108 * constructors are created. These constructors simply delegate to the superclass constructor. They are simply used to |
108 * constructors are created. These constructors simply delegate to the superclass constructor. They are simply used to |
109 * create instances of the adapter class, with no instance-level overrides, as they don't have them. |
109 * create instances of the adapter class, with no instance-level overrides, as they don't have them. If the original |
|
110 * class' constructor was variable arity, the adapter constructor will also be variable arity. Protected constructors |
|
111 * are exposed as public. |
110 * </li> |
112 * </li> |
111 * </ul> |
113 * </ul> |
112 * </p><p> |
114 * </p><p> |
113 * For adapter methods that return values, all the JavaScript-to-Java conversions supported by Nashorn will be in effect |
115 * For adapter methods that return values, all the JavaScript-to-Java conversions supported by Nashorn will be in effect |
114 * to coerce the JavaScript function return value to the expected Java return type. |
116 * to coerce the JavaScript function return value to the expected Java return type. |
188 private static final String ADAPTER_CLASS_NAME_SUFFIX = "$$NashornJavaAdapter"; |
190 private static final String ADAPTER_CLASS_NAME_SUFFIX = "$$NashornJavaAdapter"; |
189 private static final String JAVA_PACKAGE_PREFIX = "java/"; |
191 private static final String JAVA_PACKAGE_PREFIX = "java/"; |
190 private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255; |
192 private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255; |
191 |
193 |
192 private static final String CLASS_INIT = "<clinit>"; |
194 private static final String CLASS_INIT = "<clinit>"; |
193 static final String CONVERTER_INIT = "<converter-init>"; |
|
194 |
195 |
195 // Method name prefix for invoking super-methods |
196 // Method name prefix for invoking super-methods |
196 static final String SUPER_PREFIX = "super$"; |
197 static final String SUPER_PREFIX = "super$"; |
197 |
198 |
198 /** |
199 /** |
492 private void generateDelegatingConstructor(final Constructor<?> ctor) { |
493 private void generateDelegatingConstructor(final Constructor<?> ctor) { |
493 final Type originalCtorType = Type.getType(ctor); |
494 final Type originalCtorType = Type.getType(ctor); |
494 final Type[] argTypes = originalCtorType.getArgumentTypes(); |
495 final Type[] argTypes = originalCtorType.getArgumentTypes(); |
495 |
496 |
496 // All constructors must be public, even if in the superclass they were protected. |
497 // All constructors must be public, even if in the superclass they were protected. |
497 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, |
498 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC | |
|
499 (ctor.isVarArgs() ? ACC_VARARGS : 0), INIT, |
498 Type.getMethodDescriptor(originalCtorType.getReturnType(), argTypes), null, null)); |
500 Type.getMethodDescriptor(originalCtorType.getReturnType(), argTypes), null, null)); |
499 |
501 |
500 mv.visitCode(); |
502 mv.visitCode(); |
501 // Invoke super constructor with the same arguments. |
503 // Invoke super constructor with the same arguments. |
502 mv.visitVarInsn(ALOAD, 0); |
504 mv.visitVarInsn(ALOAD, 0); |
541 final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : SCRIPT_OBJECT_TYPE; |
543 final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : SCRIPT_OBJECT_TYPE; |
542 newArgTypes[argLen] = extraArgumentType; |
544 newArgTypes[argLen] = extraArgumentType; |
543 System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); |
545 System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); |
544 |
546 |
545 // All constructors must be public, even if in the superclass they were protected. |
547 // All constructors must be public, even if in the superclass they were protected. |
546 // Existing super constructor <init>(this, args...) triggers generating <init>(this, scriptObj, args...). |
548 // Existing super constructor <init>(this, args...) triggers generating <init>(this, args..., scriptObj). |
|
549 // Any variable arity constructors become fixed-arity with explicit array arguments. |
547 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, |
550 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, |
548 Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); |
551 Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); |
549 |
552 |
550 mv.visitCode(); |
553 mv.visitCode(); |
551 // First, invoke super constructor with original arguments. If the form of the constructor we're generating is |
554 // First, invoke super constructor with original arguments. If the form of the constructor we're generating is |
591 endInitMethod(mv); |
594 endInitMethod(mv); |
592 |
595 |
593 if (! fromFunction) { |
596 if (! fromFunction) { |
594 newArgTypes[argLen] = OBJECT_TYPE; |
597 newArgTypes[argLen] = OBJECT_TYPE; |
595 final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, |
598 final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, |
596 Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); |
599 Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); |
597 generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); |
600 generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); |
598 } |
601 } |
599 } |
602 } |
600 |
603 |
601 // Object additional param accepting constructor - generated to handle null and undefined value |
604 // Object additional param accepting constructor - generated to handle null and undefined value |