nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java
changeset 31277 62097549ae94
parent 27099 eceb216332cb
child 31738 5ad3dfcf3507
equal deleted inserted replaced
31216:43d0179ee9de 31277:62097549ae94
   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