com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaxp-ri Show documentation
Show all versions of jaxp-ri Show documentation
Java API for XML Processing Reference Implementation
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.10 2010-11-01 04:34:19 joehw Exp $
*/
package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
import java.util.Hashtable;
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;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;
/**
* @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;
/**
* A mapping between patterns and instruction lists used by
* test sequences to avoid compiling the same pattern multiple
* times. Note that patterns whose kernels are "*", "node()"
* and "@*" can between shared by test sequences.
*/
private Hashtable _preCompiled = new Hashtable();
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);
}
/**
* Add a pre-compiled pattern to this mode.
*/
public void addInstructionList(Pattern pattern,
InstructionList ilist)
{
_preCompiled.put(pattern, ilist);
}
/**
* Get the instruction list for a pre-compiled pattern. Used by
* test sequences to avoid compiling patterns more than once.
*/
public InstructionList getInstructionList(Pattern pattern) {
return (InstructionList) _preCompiled.get(pattern);
}
}