< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java

Print this page




 649         final Type asmType = Type.getMethodType(methodDesc);
 650         final Type[] asmArgTypes = asmType.getArgumentTypes();
 651 
 652         final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method), name,
 653                 methodDesc, null, exceptionNames));
 654         mv.visitCode();
 655 
 656         final Class<?> returnType = type.returnType();
 657         final Type asmReturnType = Type.getType(returnType);
 658 
 659         // Determine the first index for a local variable
 660         int nextLocalVar = 1; // "this" is at 0
 661         for(final Type t: asmArgTypes) {
 662             nextLocalVar += t.getSize();
 663         }
 664         // Set our local variable index
 665         final int globalRestoringRunnableVar = nextLocalVar++;
 666 
 667         // Load the creatingGlobal object
 668         loadField(mv, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 669 
 670         // stack: [creatingGlobal]
 671         SET_GLOBAL.invoke(mv);
 672         // stack: [runnable]
 673         mv.visitVarInsn(ASTORE, globalRestoringRunnableVar);
 674         // stack: []
 675 
 676         final Label tryBlockStart = new Label();
 677         mv.visitLabel(tryBlockStart);
 678 
 679         final Label callCallee = new Label();
 680         final Label defaultBehavior = new Label();
 681         // If this is a SAM type...
 682         if (samName != null) {
 683             // ...every method will be checking whether we're initialized with a
 684             // function.
 685             loadField(mv, IS_FUNCTION_FIELD_NAME, BOOLEAN_TYPE_DESCRIPTOR);
 686             // stack: [isFunction]
 687             if (name.equals(samName)) {
 688                 final Label notFunction = new Label();
 689                 mv.ifeq(notFunction);


 709                 // it'll fall back to default behavior
 710                 mv.ifne(defaultBehavior);
 711                 // stack: []
 712             }
 713         }
 714 
 715         // At this point, this is either not a SAM method or the delegate is
 716         // not a ScriptFunction. We need to emit a GET_METHOD_PROPERTY Nashorn
 717         // invokedynamic.
 718 
 719         if(name.equals("toString")) {
 720             // Since every JS Object has a toString, we only override
 721             // "String toString()" it if it's explicitly specified on the object.
 722             loadField(mv, DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 723             // stack: [delegate]
 724             HAS_OWN_TO_STRING.invoke(mv);
 725             // stack: [hasOwnToString]
 726             mv.ifeq(defaultBehavior);
 727         }
 728 





 729         loadField(mv, DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 730         mv.dup();
 731         // stack: [delegate, delegate]
 732         final String encodedName = NameCodec.encode(name);
 733         mv.visitInvokeDynamicInsn(encodedName,
 734                 GET_METHOD_PROPERTY_METHOD_DESCRIPTOR, BOOTSTRAP_HANDLE,
 735                 NashornCallSiteDescriptor.GET_METHOD_PROPERTY);
 736         // stack: [callee, delegate]
 737         mv.visitLdcInsn(name);
 738         // stack: [name, callee, delegate]
 739         CHECK_FUNCTION.invoke(mv);
 740         // stack: [fnCalleeOrNull, delegate]
 741         final Label hasFunction = new Label();
 742         mv.dup();
 743         // stack: [fnCalleeOrNull, fnCalleeOrNull, delegate]
 744         mv.ifnonnull(hasFunction);
 745         // stack: [null, delegate]
 746         // If it's null or undefined, clear stack and fall back to default
 747         // behavior.
 748         mv.pop2();




 649         final Type asmType = Type.getMethodType(methodDesc);
 650         final Type[] asmArgTypes = asmType.getArgumentTypes();
 651 
 652         final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method), name,
 653                 methodDesc, null, exceptionNames));
 654         mv.visitCode();
 655 
 656         final Class<?> returnType = type.returnType();
 657         final Type asmReturnType = Type.getType(returnType);
 658 
 659         // Determine the first index for a local variable
 660         int nextLocalVar = 1; // "this" is at 0
 661         for(final Type t: asmArgTypes) {
 662             nextLocalVar += t.getSize();
 663         }
 664         // Set our local variable index
 665         final int globalRestoringRunnableVar = nextLocalVar++;
 666 
 667         // Load the creatingGlobal object
 668         loadField(mv, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);

 669         // stack: [creatingGlobal]
 670         SET_GLOBAL.invoke(mv);
 671         // stack: [runnable]
 672         mv.visitVarInsn(ASTORE, globalRestoringRunnableVar);
 673         // stack: []
 674 
 675         final Label tryBlockStart = new Label();
 676         mv.visitLabel(tryBlockStart);
 677 
 678         final Label callCallee = new Label();
 679         final Label defaultBehavior = new Label();
 680         // If this is a SAM type...
 681         if (samName != null) {
 682             // ...every method will be checking whether we're initialized with a
 683             // function.
 684             loadField(mv, IS_FUNCTION_FIELD_NAME, BOOLEAN_TYPE_DESCRIPTOR);
 685             // stack: [isFunction]
 686             if (name.equals(samName)) {
 687                 final Label notFunction = new Label();
 688                 mv.ifeq(notFunction);


 708                 // it'll fall back to default behavior
 709                 mv.ifne(defaultBehavior);
 710                 // stack: []
 711             }
 712         }
 713 
 714         // At this point, this is either not a SAM method or the delegate is
 715         // not a ScriptFunction. We need to emit a GET_METHOD_PROPERTY Nashorn
 716         // invokedynamic.
 717 
 718         if(name.equals("toString")) {
 719             // Since every JS Object has a toString, we only override
 720             // "String toString()" it if it's explicitly specified on the object.
 721             loadField(mv, DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 722             // stack: [delegate]
 723             HAS_OWN_TO_STRING.invoke(mv);
 724             // stack: [hasOwnToString]
 725             mv.ifeq(defaultBehavior);
 726         }
 727 
 728         loadField(mv, DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 729         //For the cases like scripted overridden methods invoked from super constructors get adapter global/delegate fields as null, since we
 730         //cannot set these fields before invoking super constructor better solution is opt out of scripted overridden method if global/delegate fields
 731         //are null and invoke super method instead 
 732         mv.ifnull(defaultBehavior);
 733         loadField(mv, DELEGATE_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
 734         mv.dup();
 735         // stack: [delegate, delegate]
 736         final String encodedName = NameCodec.encode(name);
 737         mv.visitInvokeDynamicInsn(encodedName,
 738                 GET_METHOD_PROPERTY_METHOD_DESCRIPTOR, BOOTSTRAP_HANDLE,
 739                 NashornCallSiteDescriptor.GET_METHOD_PROPERTY);
 740         // stack: [callee, delegate]
 741         mv.visitLdcInsn(name);
 742         // stack: [name, callee, delegate]
 743         CHECK_FUNCTION.invoke(mv);
 744         // stack: [fnCalleeOrNull, delegate]
 745         final Label hasFunction = new Label();
 746         mv.dup();
 747         // stack: [fnCalleeOrNull, fnCalleeOrNull, delegate]
 748         mv.ifnonnull(hasFunction);
 749         // stack: [null, delegate]
 750         // If it's null or undefined, clear stack and fall back to default
 751         // behavior.
 752         mv.pop2();


< prev index next >