- /*
- * Copyright 2001-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * $Id: MethodGenerator.java,v 1.15 2004/02/16 22:26:44 minchau Exp $
- */
-
- package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
-
- import com.sun.org.apache.bcel.internal.generic.ALOAD;
- import com.sun.org.apache.bcel.internal.generic.ASTORE;
- import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
- import com.sun.org.apache.bcel.internal.generic.ICONST;
- import com.sun.org.apache.bcel.internal.generic.ILOAD;
- import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
- import com.sun.org.apache.bcel.internal.generic.ISTORE;
- import com.sun.org.apache.bcel.internal.generic.Instruction;
- import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
- import com.sun.org.apache.bcel.internal.generic.InstructionList;
- import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
- import com.sun.org.apache.bcel.internal.generic.MethodGen;
- import com.sun.org.apache.bcel.internal.generic.Type;
-
- /**
- * @author Jacek Ambroziak
- * @author Santiago Pericas-Geertsen
- */
- public class MethodGenerator extends MethodGen
- implements com.sun.org.apache.xalan.internal.xsltc.compiler.Constants {
- protected static final int INVALID_INDEX = -1;
-
- private static final String START_ELEMENT_SIG
- = "(" + STRING_SIG + ")V";
- private static final String END_ELEMENT_SIG
- = START_ELEMENT_SIG;
-
- private InstructionList _mapTypeSub;
-
- private static final int DOM_INDEX = 1;
- private static final int ITERATOR_INDEX = 2;
- private static final int HANDLER_INDEX = 3;
-
- private Instruction _iloadCurrent;
- private Instruction _istoreCurrent;
- private final Instruction _astoreHandler;
- private final Instruction _aloadHandler;
- private final Instruction _astoreIterator;
- private final Instruction _aloadIterator;
- private final Instruction _aloadDom;
- private final Instruction _astoreDom;
-
- private final Instruction _startElement;
- private final Instruction _endElement;
- private final Instruction _startDocument;
- private final Instruction _endDocument;
- private final Instruction _attribute;
- private final Instruction _uniqueAttribute;
- private final Instruction _namespace;
-
- private final Instruction _setStartNode;
- private final Instruction _reset;
- private final Instruction _nextNode;
-
- private SlotAllocator _slotAllocator;
- private boolean _allocatorInit = false;
-
- public MethodGenerator(int access_flags, Type return_type,
- Type[] arg_types, String[] arg_names,
- String method_name, String class_name,
- InstructionList il, ConstantPoolGen cpg) {
- super(access_flags, return_type, arg_types, arg_names, method_name,
- class_name, il, cpg);
-
- _astoreHandler = new ASTORE(HANDLER_INDEX);
- _aloadHandler = new ALOAD(HANDLER_INDEX);
- _astoreIterator = new ASTORE(ITERATOR_INDEX);
- _aloadIterator = new ALOAD(ITERATOR_INDEX);
- _aloadDom = new ALOAD(DOM_INDEX);
- _astoreDom = new ASTORE(DOM_INDEX);
-
- final int startElement =
- cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "startElement",
- START_ELEMENT_SIG);
- _startElement = new INVOKEINTERFACE(startElement, 2);
-
- final int endElement =
- cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "endElement",
- END_ELEMENT_SIG);
- _endElement = new INVOKEINTERFACE(endElement, 2);
-
- final int attribute =
- cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "addAttribute",
- "("
- + STRING_SIG
- + STRING_SIG
- + ")V");
- _attribute = new INVOKEINTERFACE(attribute, 3);
-
- final int uniqueAttribute =
- cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "addUniqueAttribute",
- "("
- + STRING_SIG
- + STRING_SIG
- + "I)V");
- _uniqueAttribute = new INVOKEINTERFACE(uniqueAttribute, 4);
-
- final int namespace =
- cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "namespaceAfterStartElement",
- "("
- + STRING_SIG
- + STRING_SIG
- + ")V");
- _namespace = new INVOKEINTERFACE(namespace, 3);
-
- int index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "startDocument",
- "()V");
- _startDocument = new INVOKEINTERFACE(index, 1);
-
- index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
- "endDocument",
- "()V");
- _endDocument = new INVOKEINTERFACE(index, 1);
-
-
- index = cpg.addInterfaceMethodref(NODE_ITERATOR,
- SET_START_NODE,
- SET_START_NODE_SIG);
- _setStartNode = new INVOKEINTERFACE(index, 2);
-
- index = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "reset", "()"+NODE_ITERATOR_SIG);
- _reset = new INVOKEINTERFACE(index, 1);
-
- index = cpg.addInterfaceMethodref(NODE_ITERATOR, NEXT, NEXT_SIG);
- _nextNode = new INVOKEINTERFACE(index, 1);
-
- _slotAllocator = new SlotAllocator();
- _slotAllocator.initialize(getLocalVariables());
- _allocatorInit = true;
- }
-
- /**
- * Allocates a local variable. If the slot allocator has already been
- * initialized, then call addLocalVariable2() so that the new variable
- * is known to the allocator. Failing to do this may cause the allocator
- * to return a slot that is already in use.
- */
- public LocalVariableGen addLocalVariable(String name, Type type,
- InstructionHandle start,
- InstructionHandle end)
- {
- return (_allocatorInit) ? addLocalVariable2(name, type, start)
- : super.addLocalVariable(name, type, start, end);
- }
-
- public LocalVariableGen addLocalVariable2(String name, Type type,
- InstructionHandle start)
- {
- return super.addLocalVariable(name, type,
- _slotAllocator.allocateSlot(type),
- start, null);
- }
-
- public void removeLocalVariable(LocalVariableGen lvg) {
- _slotAllocator.releaseSlot(lvg);
- super.removeLocalVariable(lvg);
- }
-
- public Instruction loadDOM() {
- return _aloadDom;
- }
-
- public Instruction storeDOM() {
- return _astoreDom;
- }
-
- public Instruction storeHandler() {
- return _astoreHandler;
- }
-
- public Instruction loadHandler() {
- return _aloadHandler;
- }
-
- public Instruction storeIterator() {
- return _astoreIterator;
- }
-
- public Instruction loadIterator() {
- return _aloadIterator;
- }
-
- public final Instruction setStartNode() {
- return _setStartNode;
- }
-
- public final Instruction reset() {
- return _reset;
- }
-
- public final Instruction nextNode() {
- return _nextNode;
- }
-
- public final Instruction startElement() {
- return _startElement;
- }
-
- public final Instruction endElement() {
- return _endElement;
- }
-
- public final Instruction startDocument() {
- return _startDocument;
- }
-
- public final Instruction endDocument() {
- return _endDocument;
- }
-
- public final Instruction attribute() {
- return _attribute;
- }
-
- public final Instruction uniqueAttribute() {
- return _uniqueAttribute;
- }
-
- public final Instruction namespace() {
- return _namespace;
- }
-
- public Instruction loadCurrentNode() {
- if (_iloadCurrent == null) {
- int idx = getLocalIndex("current");
- if (idx > 0)
- _iloadCurrent = new ILOAD(idx);
- else
- _iloadCurrent = new ICONST(0);
- }
- return _iloadCurrent;
- }
-
- public Instruction storeCurrentNode() {
- return _istoreCurrent != null
- ? _istoreCurrent
- : (_istoreCurrent = new ISTORE(getLocalIndex("current")));
- }
-
- /** by default context node is the same as current node. MK437 */
- public Instruction loadContextNode() {
- return loadCurrentNode();
- }
-
- public Instruction storeContextNode() {
- return storeCurrentNode();
- }
-
- public int getLocalIndex(String name) {
- return getLocalVariable(name).getIndex();
- }
-
- public LocalVariableGen getLocalVariable(String name) {
- final LocalVariableGen[] vars = getLocalVariables();
- for (int i = 0; i < vars.length; i++)
- if (vars[i].getName().equals(name))
- return vars[i];
- return null;
- }
-
- public void setMaxLocals() {
-
- // Get the current number of local variable slots
- int maxLocals = super.getMaxLocals();
- int prevLocals = maxLocals;
-
- // Get numer of actual variables
- final LocalVariableGen[] localVars = super.getLocalVariables();
- if (localVars != null) {
- if (localVars.length > maxLocals)
- maxLocals = localVars.length;
- }
-
- // We want at least 5 local variable slots (for parameters)
- if (maxLocals < 5) maxLocals = 5;
-
- super.setMaxLocals(maxLocals);
- }
-
- }