All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.classfilewriter.code.LocalVariableState Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 *
 * Copyright 2012 Red Hat, Inc.
 *
 * 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.
 */
package org.jboss.classfilewriter.code;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jboss.classfilewriter.ClassMethod;
import org.jboss.classfilewriter.InvalidBytecodeException;
import org.jboss.classfilewriter.constpool.ConstPool;

/**
 * In immutable local variable state
 *
 * @author Stuart Douglas
 *
 */
public class LocalVariableState {

    /**
     * The contents, null is used to represent the additional spot taken up by a wide variable.
     * 

* This list may be shared between frames, so it must never be modified *

* The very first element represents the first local variable (this for non static methods) */ private final List contents; private final ConstPool constPool; /** * construct the initial local variable state for a method */ public LocalVariableState(ClassMethod method) { this.constPool = method.getClassFile().getConstPool(); contents = new ArrayList(); if (!method.isStatic()) { if (method.isConstructor()) { contents.add(new StackEntry(StackEntryType.UNINITIALIZED_THIS, method.getClassFile().getDescriptor())); } else { contents.add(StackEntry.of(method.getClassFile().getDescriptor(), method.getClassFile().getConstPool())); } } for (String param : method.getParameters()) { StackEntry entry = StackEntry.of(param, method.getClassFile().getConstPool()); contents.add(entry); if (entry.isWide()) { contents.add(new StackEntry(StackEntryType.TOP, param)); } } } public LocalVariableState(final ConstPool pool, final String ... entries) { this.constPool = pool; contents = new ArrayList(); for(String c : entries) { final StackEntry entry = StackEntry.of(c, constPool); contents.add(entry); } } private LocalVariableState(final List contents, ConstPool constPool) { this.contents = contents; this.constPool = constPool; } public List getContents() { return Collections.unmodifiableList(contents); } public StackEntry get(int index) { return contents.get(index); } public LocalVariableState storeWide(int index, StackEntry entry) { ArrayList newContents = new ArrayList(contents.size()); for (int i = 0; i <= index || i < contents.size(); ++i) { if (index == i) { newContents.add(entry); newContents.add(new StackEntry(StackEntryType.TOP, entry.getDescriptor())); ++i; } else if (i >= contents.size()) { // write a null in unitialised slots // not sure if this is correct newContents.add(new StackEntry(StackEntryType.NULL, null)); } else { newContents.add(contents.get(i)); } } return new LocalVariableState(newContents, constPool); } public LocalVariableState store(int index, StackEntry entry) { ArrayList newContents = new ArrayList(contents.size()); for (int i = 0; i <= index || i < contents.size(); ++i) { if (index == i) { newContents.add(entry); } else if (i >= contents.size()) { // write a null in unitialised slots // not sure if this is correct newContents.add(new StackEntry(StackEntryType.NULL, null)); } else { newContents.add(contents.get(i)); } } return new LocalVariableState(newContents, constPool); } public int size() { return contents.size(); } @Override public String toString() { return "Local Variables: " + contents.toString(); } public LocalVariableState constructorCall(StackEntry entry) { List newContents = new ArrayList(contents.size()); if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) { for (int i = 0; i < contents.size(); ++i) { StackEntry stackEntry = contents.get(i); if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT && stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) { newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool)); } else { newContents.add(stackEntry); } } return new LocalVariableState(newContents, constPool); } else { throw new InvalidBytecodeException("entry is not an unitialized object. " + toString()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy