< prev index next >

jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java

Print this page




  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;
  55 import java.util.Enumeration;
  56 import java.util.HashMap;


 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      */




  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.POP;
  39 import com.sun.org.apache.bcel.internal.generic.PUSH;
  40 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
  41 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
  42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
  43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
  45 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType;
  46 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  47 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
  48 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable;
  49 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType;
  50 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType;
  51 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  52 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  53 import java.lang.reflect.Constructor;
  54 import java.lang.reflect.Method;
  55 import java.lang.reflect.Modifier;
  56 import java.util.Collections;
  57 import java.util.Enumeration;
  58 import java.util.HashMap;


 777             // Invoke the method in the basis library
 778             index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name,
 779                                      _chosenMethodType.toSignature(args));
 780             il.append(new INVOKESTATIC(index));
 781         }
 782         // Add call to BasisLibrary.unresolved_externalF() to generate
 783         // run-time error message for unsupported external functions
 784         else if (unresolvedExternal) {
 785             index = cpg.addMethodref(BASIS_LIBRARY_CLASS,
 786                                      "unresolved_externalF",
 787                                      "(Ljava/lang/String;)V");
 788             il.append(new PUSH(cpg, _fname.toString()));
 789             il.append(new INVOKESTATIC(index));
 790         }
 791         else if (_isExtConstructor) {
 792             if (isSecureProcessing && !isExtensionFunctionEnabled)
 793                 translateUnallowedExtension(cpg, il);
 794 
 795             final String clazz =
 796                 _chosenConstructor.getDeclaringClass().getName();
 797 
 798             // Generate call to Module.addReads:
 799             //   <TransletClass>.class.getModule().addReads(
 800             generateAddReads(classGen, methodGen, clazz);
 801             
 802             Class[] paramTypes = _chosenConstructor.getParameterTypes();
 803             LocalVariableGen[] paramTemp = new LocalVariableGen[n];
 804 
 805             // Backwards branches are prohibited if an uninitialized object is
 806             // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
 807             // We don't know whether this code might contain backwards branches
 808             // so we mustn't create the new object until after we've created
 809             // the suspect arguments to its constructor.  Instead we calculate
 810             // the values of the arguments to the constructor first, store them
 811             // in temporary variables, create the object and reload the
 812             // arguments from the temporaries to avoid the problem.
 813 
 814             for (int i = 0; i < n; i++) {
 815                 final Expression exp = argument(i);
 816                 Type expType = exp.getType();
 817                 exp.translate(classGen, methodGen);
 818                 // Convert the argument to its Java type
 819                 exp.startIterator(classGen, methodGen);
 820                 expType.translateTo(classGen, methodGen, paramTypes[i]);
 821                 paramTemp[i] =


 845             buffer.append("V");
 846 
 847             index = cpg.addMethodref(clazz,
 848                                      "<init>",
 849                                      buffer.toString());
 850             il.append(new INVOKESPECIAL(index));
 851 
 852             // Convert the return type back to our internal type
 853             (Type.Object).translateFrom(classGen, methodGen,
 854                                 _chosenConstructor.getDeclaringClass());
 855 
 856         }
 857         // Invoke function calls that are handled in separate classes
 858         else {
 859             if (isSecureProcessing && !isExtensionFunctionEnabled)
 860                 translateUnallowedExtension(cpg, il);
 861 
 862             final String clazz = _chosenMethod.getDeclaringClass().getName();
 863             Class[] paramTypes = _chosenMethod.getParameterTypes();
 864 
 865 
 866             // Generate call to Module.addReads:
 867             //   <TransletClass>.class.getModule().addReads(
 868             //        Class.forName(<clazz>).getModule());
 869             generateAddReads(classGen, methodGen, clazz);
 870 
 871             // Push "this" if it is an instance method
 872             if (_thisArgument != null) {
 873                 _thisArgument.translate(classGen, methodGen);
 874             }
 875 
 876             for (int i = 0; i < n; i++) {
 877                 final Expression exp = argument(i);
 878                 exp.translate(classGen, methodGen);
 879                 // Convert the argument to its Java type
 880                 exp.startIterator(classGen, methodGen);
 881                 exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
 882             }
 883 
 884             final StringBuffer buffer = new StringBuffer();
 885             buffer.append('(');
 886             for (int i = 0; i < paramTypes.length; i++) {
 887                 buffer.append(getSignature(paramTypes[i]));
 888             }
 889             buffer.append(')');
 890             buffer.append(getSignature(_chosenMethod.getReturnType()));


 892             if (_thisArgument != null && _clazz.isInterface()) {
 893                 index = cpg.addInterfaceMethodref(clazz,
 894                                      _fname.getLocalPart(),
 895                                      buffer.toString());
 896                 il.append(new INVOKEINTERFACE(index, n+1));
 897             }
 898             else {
 899                 index = cpg.addMethodref(clazz,
 900                                      _fname.getLocalPart(),
 901                                      buffer.toString());
 902                 il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) :
 903                           (InvokeInstruction) new INVOKESTATIC(index));
 904             }
 905 
 906             // Convert the return type back to our internal type
 907             _type.translateFrom(classGen, methodGen,
 908                                 _chosenMethod.getReturnType());
 909         }
 910     }
 911 
 912     private void generateAddReads(ClassGenerator classGen, MethodGenerator methodGen,
 913                           String clazz) {
 914         final ConstantPoolGen cpg = classGen.getConstantPool();
 915         final InstructionList il = methodGen.getInstructionList();
 916 
 917         if (classGen.getMajor() < com.sun.org.apache.bcel.internal.Constants.MAJOR_1_5) {
 918             // Major version needs to be >= 5.0 in order to support loading
 919             // a class ref from the constant pool (LDC)
 920             classGen.setMajor(com.sun.org.apache.bcel.internal.Constants.MAJOR_1_5);
 921             classGen.setMinor(com.sun.org.apache.bcel.internal.Constants.MINOR_1_5);
 922         }
 923 
 924         // Generate call to Module.addReads:
 925         //   <TransletClass>.class.getModule().addReads(
 926         //        Class.forName(<clazz>).getModule());
 927         // Class.forName may throw ClassNotFoundException.
 928         // This is OK as it will caught higher up the stack in
 929         // TransformerImpl.transform() and wrapped into a
 930         // TransformerException.
 931         methodGen.markChunkStart();
 932 
 933         int index = cpg.addMethodref(CLASS_CLASS,
 934                                      GET_MODULE,
 935                                      GET_MODULE_SIG);
 936         il.append(new LDC(cpg.addClass(classGen.getClassName())));
 937         il.append(new INVOKEVIRTUAL(index));
 938         int index2 = cpg.addMethodref(CLASS_CLASS,
 939                                       FOR_NAME,
 940                                       FOR_NAME_SIG);
 941         il.append(new LDC(cpg.addString(clazz)));
 942         il.append(new INVOKESTATIC(index2));
 943         il.append(new INVOKEVIRTUAL(index));
 944         index = cpg.addMethodref(MODULE_CLASS,
 945                                  ADD_READS,
 946                                  ADD_READS_SIG);
 947         il.append(new INVOKEVIRTUAL(index));
 948         il.append(new POP());
 949 
 950         methodGen.markChunkEnd();
 951     }
 952 
 953     @Override
 954     public String toString() {
 955         return "funcall(" + _fname + ", " + _arguments + ')';
 956     }
 957 
 958     public boolean isStandard() {
 959         final String namespace = _fname.getNamespace();
 960         return (namespace == null) || (namespace.equals(Constants.EMPTYSTRING));
 961     }
 962 
 963     public boolean isExtension() {
 964         final String namespace = _fname.getNamespace();
 965         return (namespace != null) && (namespace.equals(EXT_XSLTC));
 966     }
 967 
 968     /**
 969      * Returns a vector with all methods named <code>_fname</code>
 970      * after stripping its namespace or <code>null</code>
 971      * if no such methods exist.
 972      */


< prev index next >