?? items.java
字號(hào):
/** * @(#)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);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -