1 /*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 /*
21 * $Id: FunctionCall.java,v 1.2.4.1 2005/09/12 10:31:32 pvedula Exp $
22 */
23
24 package com.sun.org.apache.xalan.internal.xsltc.compiler;
25
26 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
27 import com.sun.org.apache.bcel.internal.generic.IFEQ;
28 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
29 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
30 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
31 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
32 import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
33 import com.sun.org.apache.bcel.internal.generic.InstructionList;
34 import com.sun.org.apache.bcel.internal.generic.InvokeInstruction;
35 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
36 import com.sun.org.apache.bcel.internal.generic.NEW;
37 import com.sun.org.apache.bcel.internal.generic.PUSH;
38 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
39 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType;
44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
45 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
46 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable;
47 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType;
48 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
49 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
50 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
51 import java.lang.reflect.Constructor;
52 import java.lang.reflect.Method;
53 import java.lang.reflect.Modifier;
54 import java.util.Collections;
775 // Invoke the method in the basis library
776 index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name,
777 _chosenMethodType.toSignature(args));
778 il.append(new INVOKESTATIC(index));
779 }
780 // Add call to BasisLibrary.unresolved_externalF() to generate
781 // run-time error message for unsupported external functions
782 else if (unresolvedExternal) {
783 index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
784 "unresolved_externalF",
785 "(Ljava/lang/String;)V");
786 il.append(new PUSH(cpg, _fname.toString()));
787 il.append(new INVOKESTATIC(index));
788 }
789 else if (_isExtConstructor) {
790 if (isSecureProcessing && !isExtensionFunctionEnabled)
791 translateUnallowedExtension(cpg, il);
792
793 final String clazz =
794 _chosenConstructor.getDeclaringClass().getName();
795 Class[] paramTypes = _chosenConstructor.getParameterTypes();
796 LocalVariableGen[] paramTemp = new LocalVariableGen[n];
797
798 // Backwards branches are prohibited if an uninitialized object is
799 // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
800 // We don't know whether this code might contain backwards branches
801 // so we mustn't create the new object until after we've created
802 // the suspect arguments to its constructor. Instead we calculate
803 // the values of the arguments to the constructor first, store them
804 // in temporary variables, create the object and reload the
805 // arguments from the temporaries to avoid the problem.
806
807 for (int i = 0; i < n; i++) {
808 final Expression exp = argument(i);
809 Type expType = exp.getType();
810 exp.translate(classGen, methodGen);
811 // Convert the argument to its Java type
812 exp.startIterator(classGen, methodGen);
813 expType.translateTo(classGen, methodGen, paramTypes[i]);
814 paramTemp[i] =
838 buffer.append("V");
839
840 index = cpg.addMethodref(clazz,
841 "<init>",
842 buffer.toString());
843 il.append(new INVOKESPECIAL(index));
844
845 // Convert the return type back to our internal type
846 (Type.Object).translateFrom(classGen, methodGen,
847 _chosenConstructor.getDeclaringClass());
848
849 }
850 // Invoke function calls that are handled in separate classes
851 else {
852 if (isSecureProcessing && !isExtensionFunctionEnabled)
853 translateUnallowedExtension(cpg, il);
854
855 final String clazz = _chosenMethod.getDeclaringClass().getName();
856 Class[] paramTypes = _chosenMethod.getParameterTypes();
857
858 // Push "this" if it is an instance method
859 if (_thisArgument != null) {
860 _thisArgument.translate(classGen, methodGen);
861 }
862
863 for (int i = 0; i < n; i++) {
864 final Expression exp = argument(i);
865 exp.translate(classGen, methodGen);
866 // Convert the argument to its Java type
867 exp.startIterator(classGen, methodGen);
868 exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
869 }
870
871 final StringBuffer buffer = new StringBuffer();
872 buffer.append('(');
873 for (int i = 0; i < paramTypes.length; i++) {
874 buffer.append(getSignature(paramTypes[i]));
875 }
876 buffer.append(')');
877 buffer.append(getSignature(_chosenMethod.getReturnType()));
879 if (_thisArgument != null && _clazz.isInterface()) {
880 index = cpg.addInterfaceMethodref(clazz,
881 _fname.getLocalPart(),
882 buffer.toString());
883 il.append(new INVOKEINTERFACE(index, n+1));
884 }
885 else {
886 index = cpg.addMethodref(clazz,
887 _fname.getLocalPart(),
888 buffer.toString());
889 il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) :
890 (InvokeInstruction) new INVOKESTATIC(index));
891 }
892
893 // Convert the return type back to our internal type
894 _type.translateFrom(classGen, methodGen,
895 _chosenMethod.getReturnType());
896 }
897 }
898
899 @Override
900 public String toString() {
901 return "funcall(" + _fname + ", " + _arguments + ')';
902 }
903
904 public boolean isStandard() {
905 final String namespace = _fname.getNamespace();
906 return (namespace == null) || (namespace.equals(Constants.EMPTYSTRING));
907 }
908
909 public boolean isExtension() {
910 final String namespace = _fname.getNamespace();
911 return (namespace != null) && (namespace.equals(EXT_XSLTC));
912 }
913
914 /**
915 * Returns a vector with all methods named <code>_fname</code>
916 * after stripping its namespace or <code>null</code>
917 * if no such methods exist.
918 */
|
1 /*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 /*
21 * $Id: FunctionCall.java,v 1.2.4.1 2005/09/12 10:31:32 pvedula Exp $
22 */
23
24 package com.sun.org.apache.xalan.internal.xsltc.compiler;
25
26 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
27 import com.sun.org.apache.bcel.internal.generic.IFEQ;
28 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
29 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
30 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
31 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
32 import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
33 import com.sun.org.apache.bcel.internal.generic.InstructionList;
34 import com.sun.org.apache.bcel.internal.generic.InvokeInstruction;
35 import com.sun.org.apache.bcel.internal.generic.LDC;
36 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
37 import com.sun.org.apache.bcel.internal.generic.NEW;
38 import com.sun.org.apache.bcel.internal.generic.PUSH;
39 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
40 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType;
45 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
46 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
47 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable;
48 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType;
49 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
50 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
51 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
52 import java.lang.reflect.Constructor;
53 import java.lang.reflect.Method;
54 import java.lang.reflect.Modifier;
55 import java.util.Collections;
776 // Invoke the method in the basis library
777 index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name,
778 _chosenMethodType.toSignature(args));
779 il.append(new INVOKESTATIC(index));
780 }
781 // Add call to BasisLibrary.unresolved_externalF() to generate
782 // run-time error message for unsupported external functions
783 else if (unresolvedExternal) {
784 index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
785 "unresolved_externalF",
786 "(Ljava/lang/String;)V");
787 il.append(new PUSH(cpg, _fname.toString()));
788 il.append(new INVOKESTATIC(index));
789 }
790 else if (_isExtConstructor) {
791 if (isSecureProcessing && !isExtensionFunctionEnabled)
792 translateUnallowedExtension(cpg, il);
793
794 final String clazz =
795 _chosenConstructor.getDeclaringClass().getName();
796
797 // Generate call to Module.addReads:
798 // <TransletClass>.class.getModule().addReads(
799 generateAddReads(classGen, methodGen, clazz);
800
801 Class[] paramTypes = _chosenConstructor.getParameterTypes();
802 LocalVariableGen[] paramTemp = new LocalVariableGen[n];
803
804 // Backwards branches are prohibited if an uninitialized object is
805 // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
806 // We don't know whether this code might contain backwards branches
807 // so we mustn't create the new object until after we've created
808 // the suspect arguments to its constructor. Instead we calculate
809 // the values of the arguments to the constructor first, store them
810 // in temporary variables, create the object and reload the
811 // arguments from the temporaries to avoid the problem.
812
813 for (int i = 0; i < n; i++) {
814 final Expression exp = argument(i);
815 Type expType = exp.getType();
816 exp.translate(classGen, methodGen);
817 // Convert the argument to its Java type
818 exp.startIterator(classGen, methodGen);
819 expType.translateTo(classGen, methodGen, paramTypes[i]);
820 paramTemp[i] =
844 buffer.append("V");
845
846 index = cpg.addMethodref(clazz,
847 "<init>",
848 buffer.toString());
849 il.append(new INVOKESPECIAL(index));
850
851 // Convert the return type back to our internal type
852 (Type.Object).translateFrom(classGen, methodGen,
853 _chosenConstructor.getDeclaringClass());
854
855 }
856 // Invoke function calls that are handled in separate classes
857 else {
858 if (isSecureProcessing && !isExtensionFunctionEnabled)
859 translateUnallowedExtension(cpg, il);
860
861 final String clazz = _chosenMethod.getDeclaringClass().getName();
862 Class[] paramTypes = _chosenMethod.getParameterTypes();
863
864
865 // Generate call to Module.addReads:
866 // <TransletClass>.class.getModule().addReads(
867 // Class.forName(<clazz>).getModule());
868 generateAddReads(classGen, methodGen, clazz);
869
870 // Push "this" if it is an instance method
871 if (_thisArgument != null) {
872 _thisArgument.translate(classGen, methodGen);
873 }
874
875 for (int i = 0; i < n; i++) {
876 final Expression exp = argument(i);
877 exp.translate(classGen, methodGen);
878 // Convert the argument to its Java type
879 exp.startIterator(classGen, methodGen);
880 exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
881 }
882
883 final StringBuffer buffer = new StringBuffer();
884 buffer.append('(');
885 for (int i = 0; i < paramTypes.length; i++) {
886 buffer.append(getSignature(paramTypes[i]));
887 }
888 buffer.append(')');
889 buffer.append(getSignature(_chosenMethod.getReturnType()));
891 if (_thisArgument != null && _clazz.isInterface()) {
892 index = cpg.addInterfaceMethodref(clazz,
893 _fname.getLocalPart(),
894 buffer.toString());
895 il.append(new INVOKEINTERFACE(index, n+1));
896 }
897 else {
898 index = cpg.addMethodref(clazz,
899 _fname.getLocalPart(),
900 buffer.toString());
901 il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) :
902 (InvokeInstruction) new INVOKESTATIC(index));
903 }
904
905 // Convert the return type back to our internal type
906 _type.translateFrom(classGen, methodGen,
907 _chosenMethod.getReturnType());
908 }
909 }
910
911 private void generateAddReads(ClassGenerator classGen, MethodGenerator methodGen,
912 String clazz) {
913 final ConstantPoolGen cpg = classGen.getConstantPool();
914 final InstructionList il = methodGen.getInstructionList();
915
916 // Generate call to Module.addReads:
917 // <TransletClass>.class.getModule().addReads(
918 // Class.forName(<clazz>).getModule());
919 // Class.forName may throw ClassNotFoundException.
920 // This is OK as it will caught higher up the stack in
921 // TransformerImpl.transform() and wrapped into a
922 // TransformerException.
923 methodGen.markChunkStart();
924
925 int index = cpg.addMethodref(CLASS_CLASS,
926 GET_MODULE,
927 GET_MODULE_SIG);
928 int index2 = cpg.addMethodref(CLASS_CLASS,
929 FOR_NAME,
930 FOR_NAME_SIG);
931 il.append(new LDC(cpg.addString(classGen.getClassName())));
932 il.append(new INVOKESTATIC(index2));
933 il.append(new INVOKEVIRTUAL(index));
934 il.append(new LDC(cpg.addString(clazz)));
935 il.append(new INVOKESTATIC(index2));
936 il.append(new INVOKEVIRTUAL(index));
937 index = cpg.addMethodref(MODULE_CLASS,
938 ADD_READS,
939 ADD_READS_SIG);
940 il.append(new INVOKEVIRTUAL(index));
941 il.append(InstructionConstants.POP);
942
943 methodGen.markChunkEnd();
944 }
945
946 @Override
947 public String toString() {
948 return "funcall(" + _fname + ", " + _arguments + ')';
949 }
950
951 public boolean isStandard() {
952 final String namespace = _fname.getNamespace();
953 return (namespace == null) || (namespace.equals(Constants.EMPTYSTRING));
954 }
955
956 public boolean isExtension() {
957 final String namespace = _fname.getNamespace();
958 return (namespace != null) && (namespace.equals(EXT_XSLTC));
959 }
960
961 /**
962 * Returns a vector with all methods named <code>_fname</code>
963 * after stripping its namespace or <code>null</code>
964 * if no such methods exist.
965 */
|