⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 items.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * @(#)Items.java	1.22 03/01/23
 *
 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.sun.tools.javac.v8.comp;
import com.sun.tools.javac.v8.util.*;

import com.sun.tools.javac.v8.code.*;

import com.sun.tools.javac.v8.code.Symbol.*;

import com.sun.tools.javac.v8.code.Type.*;

import com.sun.tools.javac.v8.code.Code.*;

import com.sun.tools.javac.v8.tree.Tree;


/**
 * A helper class for code generation. Items are objects
 *  that stand for addressable entities in the bytecode. Each item
 *  supports a fixed protocol for loading the item on the stack, storing
 *  into it, converting it into a jump condition, and several others.
 *  There are many individual forms of items, such as local, static,
 *  indexed, or instance variables, values on the top of stack, the
 *  special values this or super, etc. Individual items are represented as
 *  inner classes in class Items.
 */
public class Items implements ByteCodes, TypeTags {

    /**
     * The current constant pool.
     */
    Pool pool;

    /**
     * The current code buffer.
     */
    Code code;

    /**
     * The current symbol table.
     */
    Symtab syms;

    /**
     * Items that exist only once (flyweight pattern).
     */
    private final Item voidItem;
    private final Item thisItem;
    private final Item superItem;
    private final Item[] stackItem = new Item[TypeCodeCount];

    public Items(Pool pool, Code code, Symtab syms) {
        super();
        this.code = code;
        this.pool = pool;
        voidItem = new Item(VOIDcode) {


                       public String toString() {
                           return "void";
                       }
                   };
        thisItem = new SelfItem(false);
        superItem = new SelfItem(true);
        for (int i = 0; i < VOIDcode; i++)
            stackItem[i] = new StackItem(i);
        stackItem[VOIDcode] = voidItem;
        this.syms = syms;
    }

    /**
      * Make a void item
      */
    Item makeVoidItem() {
        return voidItem;
    }

    /**
      * Make an item representing `this'.
      */
    Item makeThisItem() {
        return thisItem;
    }

    /**
      * Make an item representing `super'.
      */
    Item makeSuperItem() {
        return superItem;
    }

    /**
      * Make an item representing a value on stack.
      *  @param type    The value's type.
      */
    Item makeStackItem(Type type) {
        return stackItem[Code.typecode(type)];
    }

    /**
      * Make an item representing an indexed expression.
      *  @param type    The expression's type.
      */
    Item makeIndexedItem(Type type) {
        return new IndexedItem(type);
    }

    /**
      * Make an item representing a local variable.
      *  @param v    The represented variable.
      */
    Item makeLocalItem(VarSymbol v) {
        return new LocalItem(v.erasure(), v.adr);
    }

    /**
      * Make an item representing a local anonymous variable.
      *  @param type  The represented variable's type.
      *  @param reg   The represented variable's register.
      */
    Item makeLocalItem(Type type, int reg) {
        return new LocalItem(type, reg);
    }

    /**
      * Make an item representing a static variable or method.
      *  @param member   The represented symbol.
      */
    Item makeStaticItem(Symbol member) {
        return new StaticItem(member);
    }

    /**
      * Make an item representing an instance variable or method.
      *  @param member       The represented symbol.
      *  @param nonvirtual   Is the reference not virtual? (true for constructors
      *                      and private members).
      */
    Item makeMemberItem(Symbol member, boolean nonvirtual) {
        return new MemberItem(member, nonvirtual);
    }

    /**
      * Make an item representing a literal.
      *  @param t      The literal's type.
      *  @param value  The literal's value.
      */
    Item makeImmediateItem(Type type, Object value) {
        return new ImmediateItem(type, value);
    }

    /**
      * Make an item representing an assignment expression.
      *  @param lhs      The item representing the assignment's left hand side.
      */
    Item makeAssignItem(Item lhs) {
        return new AssignItem(lhs);
    }

    /**
      * Make an item representing a conditional or unconditional jump.
      *  @param opcode      The jump's opcode.
      *  @param trueJumps   A chain encomassing all jumps that can be taken
      *                     if the condition evaluates to true.
      *  @param falseJumps  A chain encomassing all jumps that can be taken
      *                     if the condition evaluates to false.
      */
    CondItem makeCondItem(int opcode, Chain truejumps, Chain falsejumps) {
        return new CondItem(opcode, truejumps, falsejumps);
    }

    /**
      * Make an item representing a conditional or unconditional jump.
      *  @param opcode      The jump's opcode.
      */
    CondItem makeCondItem(int opcode) {
        return makeCondItem(opcode, null, null);
    }

    /**
      * The base class of all items, which implements default behavior.
      */
    abstract class Item {

        /**
         * The type code of values represented by this item.
         */
        int typecode;

        Item(int typecode) {
            super();
            this.typecode = typecode;
        }

        /**
          * Generate code to load this item onto stack.
          */
        Item load() {
            throw new AssertionError();
        }

        /**
          * Generate code to store top of stack into this item.
          */
        Item store() {
            throw new AssertionError("store unsupported: " + this);
        }

        /**
          * Generate code to invoke method represented by this item.
          */
        Item invoke() {
            throw new AssertionError(this.toString());
        }

        /**
          * Generate code to use this item twice.
          */
        void duplicate() {
        }

        /**
          * Generate code to avoid having to use this item.
          */
        void drop() {
        }

        /**
          * Generate code to stash a copy of top of stack - of typecode toscode -
          *  under this item.
          */
        void stash(int toscode) {
            stackItem[toscode].duplicate();
        }

        /**
          * Generate code to turn item into a testable condition.
          */
        CondItem mkCond() {
            load();
            return makeCondItem(ifne);
        }

        /**
          * Generate code to coerce item to given type code.
          *  @param targetcode    The type code to coerce to.
          */
        Item coerce(int targetcode) {
            if (typecode == targetcode)
                return this;
            else {
                load();
                int typecode1 = Code.truncate(typecode);
                int targetcode1 = Code.truncate(targetcode);
                if (typecode1 != targetcode1) {
                    int offset =
                            targetcode1 > typecode1 ? targetcode1 - 1 : targetcode1;
                    code.emitop(i2l + typecode1 * 3 + offset);
                }
                if (targetcode != targetcode1) {
                    code.emitop(int2byte + targetcode - BYTEcode);
                }
                return stackItem[targetcode];
            }
        }

        /**
          * Generate code to coerce item to given type.
          *  @param targettype    The type to coerce to.
          */
        Item coerce(Type targettype) {
            return coerce(Code.typecode(targettype));
        }

        /**
          * Return the width of this item on stack as a number of words.
          */
        int width() {
            return 0;
        }

        public abstract String toString();
    }

    /**
      * An item representing a value on stack.
      */
    class StackItem extends Item {

        StackItem(int typecode) {
            super(typecode);
        }

        Item load() {
            return this;
        }

        void duplicate() {
            code.emitop(width() == 2 ? dup2 : dup);
        }

        void drop() {
            code.emitop(width() == 2 ? pop2 : pop);
        }

        void stash(int toscode) {
            code.emitop((width() == 2 ? dup_x2 : dup_x1) +
                    3 * (Code.width(toscode) - 1));
        }

        int width() {
            return Code.width(typecode);
        }

        public String toString() {
            return "stack(" + typecodeNames[typecode] + ")";
        }
    }

    /**
      * An item representing an indexed expression.
      */
    class IndexedItem extends Item {

        IndexedItem(Type type) {
            super(Code.typecode(type));
        }

        Item load() {
            code.emitop(iaload + typecode);
            return stackItem[typecode];
        }

        Item store() {
            code.emitop(iastore + typecode);
            return voidItem;
        }

        void duplicate() {
            code.emitop(dup2);
        }

        void drop() {
            code.emitop(pop2);
        }

        void stash(int toscode) {
            code.emitop(dup_x2 + 3 * (Code.width(toscode) - 1));
        }

        int width() {
            return 2;
        }

        public String toString() {
            return "indexed(" + ByteCodes.typecodeNames[typecode] + ")";
        }
    }

    /**
      * An item representing `this' or `super'.
      */
    class SelfItem extends Item {

        /**
         * Flag which determines whether this item represents `this' or `super'.
         */
        boolean isSuper;

        SelfItem(boolean isSuper) {
            super(OBJECTcode);
            this.isSuper = isSuper;
        }

        Item load() {
            code.emitop(aload_0);
            return stackItem[typecode];
        }

        public String toString() {
            return isSuper ? "super" : "this";
        }
    }

    /**
      * An item representing a local variable.
      */
    class LocalItem extends Item {

        /**
         * The variable's register.
         */
        int reg;

        /**
         * The variable's type.
         */
        Type type;

        LocalItem(Type type, int reg) {
            super(Code.typecode(type));
            assert reg >= 0;
            this.type = type;
            this.reg = reg;
        }

        Item load() {
            if (reg <= 3)
                code.emitop(iload_0 + Code.truncate(typecode) * 4 + reg);
            else
                code.emitop1w(iload + Code.truncate(typecode), reg);
            return stackItem[typecode];
        }

        Item store() {
            if (reg <= 3)
                code.emitop(istore_0 + Code.truncate(typecode) * 4 + reg);
            else
                code.emitop1w(istore + Code.truncate(typecode), reg);
            code.setDefined(reg);
            return voidItem;
        }

        void incr(int x) {
            if (typecode == INTcode) {
                code.emitop1w(iinc, reg);
                if (reg > 255)
                    code.emit2(x);
                else
                    code.emit1(x);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -