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

com.github.rapidark.framework.thirdparty.asm.Frame Maven / Gradle / Ivy

The newest version!
package com.github.rapidark.framework.thirdparty.asm;

final class Frame {
	static final int DIM = -268435456;
	static final int ARRAY_OF = 268435456;
	static final int ELEMENT_OF = -268435456;
	static final int KIND = 251658240;
	static final int TOP_IF_LONG_OR_DOUBLE = 8388608;
	static final int VALUE = 8388607;
	static final int BASE_KIND = 267386880;
	static final int BASE_VALUE = 1048575;
	static final int BASE = 16777216;
	static final int OBJECT = 24117248;
	static final int UNINITIALIZED = 25165824;
	private static final int LOCAL = 33554432;
	private static final int STACK = 50331648;
	static final int TOP = 16777216;
	static final int BOOLEAN = 16777225;
	static final int BYTE = 16777226;
	static final int CHAR = 16777227;
	static final int SHORT = 16777228;
	static final int INTEGER = 16777217;
	static final int FLOAT = 16777218;
	static final int DOUBLE = 16777219;
	static final int LONG = 16777220;
	static final int NULL = 16777221;
	static final int UNINITIALIZED_THIS = 16777222;
	static final int[] SIZE;
	Label owner;
	int[] inputLocals;
	int[] inputStack;
	private int[] outputLocals;
	private int[] outputStack;
	private int outputStackTop;
	private int initializationCount;
	private int[] initializations;

	static {
		int[] b = new int['Ê'];
		String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDDCDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCDCDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFEDDDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE";
		for (int i = 0; i < b.length; i++) {
			b[i] = (s.charAt(i) - 'E');
		}
		SIZE = b;
	}

	private int get(int local) {
		if ((this.outputLocals == null) || (local >= this.outputLocals.length)) {
			return 0x2000000 | local;
		}
		int type = this.outputLocals[local];
		if (type == 0) {
			type = this.outputLocals[local] = 0x2000000 | local;
		}
		return type;
	}

	private void set(int local, int type) {
		if (this.outputLocals == null) {
			this.outputLocals = new int[10];
		}
		int n = this.outputLocals.length;
		if (local >= n) {
			int[] t = new int[Math.max(local + 1, 2 * n)];
			System.arraycopy(this.outputLocals, 0, t, 0, n);
			this.outputLocals = t;
		}
		this.outputLocals[local] = type;
	}

	private void push(int type) {
		if (this.outputStack == null) {
			this.outputStack = new int[10];
		}
		int n = this.outputStack.length;
		if (this.outputStackTop >= n) {
			int[] t = new int[Math.max(this.outputStackTop + 1, 2 * n)];
			System.arraycopy(this.outputStack, 0, t, 0, n);
			this.outputStack = t;
		}
		this.outputStack[(this.outputStackTop++)] = type;

		int top = this.owner.inputStackTop + this.outputStackTop;
		if (top > this.owner.outputStackMax) {
			this.owner.outputStackMax = top;
		}
	}

	private void push(ClassWriter cw, String desc) {
		int type = type(cw, desc);
		if (type != 0) {
			push(type);
			if ((type == 16777220) || (type == 16777219)) {
				push(16777216);
			}
		}
	}

	private static int type(ClassWriter cw, String desc) {
		int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
		switch (desc.charAt(index)) {
		case 'V':
			return 0;
		case 'B':
		case 'C':
		case 'I':
		case 'S':
		case 'Z':
			return 16777217;
		case 'F':
			return 16777218;
		case 'J':
			return 16777220;
		case 'D':
			return 16777219;
		case 'L':
			String t = desc.substring(index + 1, desc.length() - 1);
			return 0x1700000 | cw.addType(t);
		}
		int dims = index + 1;
		while (desc.charAt(dims) == '[') {
			dims++;
		}
		int data;
		switch (desc.charAt(dims)) {
		case 'Z':
			data = 16777225;
			break;
		case 'C':
			data = 16777227;
			break;
		case 'B':
			data = 16777226;
			break;
		case 'S':
			data = 16777228;
			break;
		case 'I':
			data = 16777217;
			break;
		case 'F':
			data = 16777218;
			break;
		case 'J':
			data = 16777220;
			break;
		case 'D':
			data = 16777219;
			break;
		default:
			String t = desc.substring(dims + 1, desc.length() - 1);
			data = 0x1700000 | cw.addType(t);
		}
		return dims - index << 28 | data;
	}

	private int pop() {
		if (outputStackTop > 0)
			return outputStack[--outputStackTop];
		else
			return 0x3000000 | --owner.inputStackTop;
	}

	private void pop(int elements) {
		if (this.outputStackTop >= elements) {
			this.outputStackTop -= elements;
		} else {
			this.owner.inputStackTop -= elements - this.outputStackTop;
			this.outputStackTop = 0;
		}
	}

	private void pop(String desc) {
		char c = desc.charAt(0);
		if (c == '(') {
			pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
		} else if ((c == 'J') || (c == 'D')) {
			pop(2);
		} else {
			pop(1);
		}
	}

	private void init(int var) {
		if (this.initializations == null) {
			this.initializations = new int[2];
		}
		int n = this.initializations.length;
		if (this.initializationCount >= n) {
			int[] t = new int[Math.max(this.initializationCount + 1, 2 * n)];
			System.arraycopy(this.initializations, 0, t, 0, n);
			this.initializations = t;
		}
		this.initializations[(this.initializationCount++)] = var;
	}

	private int init(ClassWriter cw, int t) {
		int s;
		if (t == 16777222) {
			s = 0x1700000 | cw.addType(cw.thisName);
		} else {
			if ((t & 0xFFF00000) == 25165824) {
				String type = cw.typeTable[(t & 0xFFFFF)].strVal1;
				s = 0x1700000 | cw.addType(type);
			} else {
				return t;
			}
		}
		for (int j = 0; j < this.initializationCount; j++) {
			int u = this.initializations[j];
			int dim = u & 0xF0000000;
			int kind = u & 0xF000000;
			if (kind == 33554432) {
				u = dim + this.inputLocals[(u & 0x7FFFFF)];
			} else if (kind == 50331648) {
				u = dim + this.inputStack[(this.inputStack.length - (u & 0x7FFFFF))];
			}
			if (t == u) {
				return s;
			}
		}
		return t;
	}

	void initInputFrame(ClassWriter cw, int access, Type[] args, int maxLocals) {
		this.inputLocals = new int[maxLocals];
		this.inputStack = new int[0];
		int i = 0;
		if ((access & 0x8) == 0) {
			if ((access & 0x80000) == 0) {
				this.inputLocals[(i++)] = (0x1700000 | cw.addType(cw.thisName));
			} else {
				this.inputLocals[(i++)] = 16777222;
			}
		}
		for (int j = 0; j < args.length; j++) {
			int t = type(cw, args[j].getDescriptor());
			this.inputLocals[(i++)] = t;
			if ((t == 16777220) || (t == 16777219)) {
				this.inputLocals[(i++)] = 16777216;
			}
		}
		while (i < maxLocals) {
			this.inputLocals[(i++)] = 16777216;
		}
	}

	void execute(int opcode, int arg, ClassWriter cw, Item item) {
		switch (opcode) {
		case 0:
		case 116:
		case 117:
		case 118:
		case 119:
		case 145:
		case 146:
		case 147:
		case 167:
		case 177:
			break;
		case 1:
			push(16777221);
			break;
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 16:
		case 17:
		case 21:
			push(16777217);
			break;
		case 9:
		case 10:
		case 22:
			push(16777220);
			push(16777216);
			break;
		case 11:
		case 12:
		case 13:
		case 23:
			push(16777218);
			break;
		case 14:
		case 15:
		case 24:
			push(16777219);
			push(16777216);
			break;
		case 18:
			switch (item.type) {
			case 3:
				push(16777217);
				break;
			case 5:
				push(16777220);
				push(16777216);
				break;
			case 4:
				push(16777218);
				break;
			case 6:
				push(16777219);
				push(16777216);
				break;
			case 7:
				push(0x1700000 | cw.addType("java/lang/Class"));
				break;
			case 8:
				push(0x1700000 | cw.addType("java/lang/String"));
				break;
			case 16:
				push(0x1700000 | cw.addType("java/lang/invoke/MethodType"));
				break;
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			default:
				push(0x1700000 | cw.addType("java/lang/invoke/MethodHandle"));
			}
			break;
		case 25:
			push(get(arg));
			break;
		case 46:
		case 51:
		case 52:
		case 53:
			pop(2);
			push(16777217);
			break;
		case 47:
		case 143:
			pop(2);
			push(16777220);
			push(16777216);
			break;
		case 48:
			pop(2);
			push(16777218);
			break;
		case 49:
		case 138:
			pop(2);
			push(16777219);
			push(16777216);
			break;
		case 50:
			pop(1);
			int t1 = pop();
			push(-268435456 + t1);
			break;
		case 54:
		case 56:
		case 58:
			t1 = pop();
			set(arg, t1);
			if (arg > 0) {
				int t2 = get(arg - 1);
				if ((t2 == 16777220) || (t2 == 16777219)) {
					set(arg - 1, 16777216);
				} else if ((t2 & 0xF000000) != 16777216) {
					set(arg - 1, t2 | 0x800000);
				}
			}
			break;
		case 55:
		case 57:
			pop(1);
			t1 = pop();
			set(arg, t1);
			set(arg + 1, 16777216);
			if (arg > 0) {
				int t2 = get(arg - 1);
				if ((t2 == 16777220) || (t2 == 16777219)) {
					set(arg - 1, 16777216);
				} else if ((t2 & 0xF000000) != 16777216) {
					set(arg - 1, t2 | 0x800000);
				}
			}
			break;
		case 79:
		case 81:
		case 83:
		case 84:
		case 85:
		case 86:
			pop(3);
			break;
		case 80:
		case 82:
			pop(4);
			break;
		case 87:
		case 153:
		case 154:
		case 155:
		case 156:
		case 157:
		case 158:
		case 170:
		case 171:
		case 172:
		case 174:
		case 176:
		case 191:
		case 194:
		case 195:
		case 198:
		case 199:
			pop(1);
			break;
		case 88:
		case 159:
		case 160:
		case 161:
		case 162:
		case 163:
		case 164:
		case 165:
		case 166:
		case 173:
		case 175:
			pop(2);
			break;
		case 89:
			t1 = pop();
			push(t1);
			push(t1);
			break;
		case 90:
			t1 = pop();
			int t2 = pop();
			push(t1);
			push(t2);
			push(t1);
			break;
		case 91:
			t1 = pop();
			t2 = pop();
			int t3 = pop();
			push(t1);
			push(t3);
			push(t2);
			push(t1);
			break;
		case 92:
			t1 = pop();
			t2 = pop();
			push(t2);
			push(t1);
			push(t2);
			push(t1);
			break;
		case 93:
			t1 = pop();
			t2 = pop();
			t3 = pop();
			push(t2);
			push(t1);
			push(t3);
			push(t2);
			push(t1);
			break;
		case 94:
			t1 = pop();
			t2 = pop();
			t3 = pop();
			int t4 = pop();
			push(t2);
			push(t1);
			push(t4);
			push(t3);
			push(t2);
			push(t1);
			break;
		case 95:
			t1 = pop();
			t2 = pop();
			push(t1);
			push(t2);
			break;
		case 96:
		case 100:
		case 104:
		case 108:
		case 112:
		case 120:
		case 122:
		case 124:
		case 126:
		case 128:
		case 130:
		case 136:
		case 142:
		case 149:
		case 150:
			pop(2);
			push(16777217);
			break;
		case 97:
		case 101:
		case 105:
		case 109:
		case 113:
		case 127:
		case 129:
		case 131:
			pop(4);
			push(16777220);
			push(16777216);
			break;
		case 98:
		case 102:
		case 106:
		case 110:
		case 114:
		case 137:
		case 144:
			pop(2);
			push(16777218);
			break;
		case 99:
		case 103:
		case 107:
		case 111:
		case 115:
			pop(4);
			push(16777219);
			push(16777216);
			break;
		case 121:
		case 123:
		case 125:
			pop(3);
			push(16777220);
			push(16777216);
			break;
		case 132:
			set(arg, 16777217);
			break;
		case 133:
		case 140:
			pop(1);
			push(16777220);
			push(16777216);
			break;
		case 134:
			pop(1);
			push(16777218);
			break;
		case 135:
		case 141:
			pop(1);
			push(16777219);
			push(16777216);
			break;
		case 139:
		case 190:
		case 193:
			pop(1);
			push(16777217);
			break;
		case 148:
		case 151:
		case 152:
			pop(4);
			push(16777217);
			break;
		case 168:
		case 169:
			throw new RuntimeException("JSR/RET are not supported with computeFrames option");
		case 178:
			push(cw, item.strVal3);
			break;
		case 179:
			pop(item.strVal3);
			break;
		case 180:
			pop(1);
			push(cw, item.strVal3);
			break;
		case 181:
			pop(item.strVal3);
			pop();
			break;
		case 182:
		case 183:
		case 184:
		case 185:
			pop(item.strVal3);
			if (opcode != 184) {
				t1 = pop();
				if ((opcode == 183) && (item.strVal2.charAt(0) == '<')) {
					init(t1);
				}
			}
			push(cw, item.strVal3);
			break;
		case 186:
			pop(item.strVal2);
			push(cw, item.strVal2);
			break;
		case 187:
			push(0x1800000 | cw.addUninitializedType(item.strVal1, arg));
			break;
		case 188:
			pop();
			switch (arg) {
			case 4:
				push(285212681);
				break;
			case 5:
				push(285212683);
				break;
			case 8:
				push(285212682);
				break;
			case 9:
				push(285212684);
				break;
			case 10:
				push(285212673);
				break;
			case 6:
				push(285212674);
				break;
			case 7:
				push(285212675);
				break;
			default:
				push(285212676);
			}
			break;
		case 189:
			String s = item.strVal1;
			pop();
			if (s.charAt(0) == '[') {
				push(cw, '[' + s);
			} else {
				push(0x11700000 | cw.addType(s));
			}
			break;
		case 192:
			s = item.strVal1;
			pop();
			if (s.charAt(0) == '[') {
				push(cw, s);
			} else {
				push(0x1700000 | cw.addType(s));
			}
			break;
		case 19:
		case 20:
		case 26:
		case 27:
		case 28:
		case 29:
		case 30:
		case 31:
		case 32:
		case 33:
		case 34:
		case 35:
		case 36:
		case 37:
		case 38:
		case 39:
		case 40:
		case 41:
		case 42:
		case 43:
		case 44:
		case 45:
		case 59:
		case 60:
		case 61:
		case 62:
		case 63:
		case 64:
		case 65:
		case 66:
		case 67:
		case 68:
		case 69:
		case 70:
		case 71:
		case 72:
		case 73:
		case 74:
		case 75:
		case 76:
		case 77:
		case 78:
		case 196:
		case 197:
		default:
			pop(arg);
			push(cw, item.strVal1);
		}
	}

	boolean merge(ClassWriter cw, Frame frame, int edge) {
		boolean changed = false;

		int nLocal = this.inputLocals.length;
		int nStack = this.inputStack.length;
		if (frame.inputLocals == null) {
			frame.inputLocals = new int[nLocal];
			changed = true;
		}
		for (int i = 0; i < nLocal; i++) {
			int t;
			if ((this.outputLocals != null) && (i < this.outputLocals.length)) {
				int s = this.outputLocals[i];
				if (s == 0) {
					t = this.inputLocals[i];
				} else {
					int dim = s & 0xF0000000;
					int kind = s & 0xF000000;
					if (kind == 16777216) {
						t = s;
					} else {
						if (kind == 33554432) {
							t = dim + this.inputLocals[(s & 0x7FFFFF)];
						} else {
							t = dim + this.inputStack[(nStack - (s & 0x7FFFFF))];
						}
						if (((s & 0x800000) != 0) && ((t == 16777220) || (t == 16777219))) {
							t = 16777216;
						}
					}
				}
			} else {
				t = this.inputLocals[i];
			}
			if (this.initializations != null) {
				t = init(cw, t);
			}
			changed |= merge(cw, t, frame.inputLocals, i);
		}
		if (edge > 0) {
			for (int i = 0; i < nLocal; i++) {
				int t = this.inputLocals[i];
				changed |= merge(cw, t, frame.inputLocals, i);
			}
			if (frame.inputStack == null) {
				frame.inputStack = new int[1];
				changed = true;
			}
			changed |= merge(cw, edge, frame.inputStack, 0);
			return changed;
		}
		int nInputStack = this.inputStack.length + this.owner.inputStackTop;
		if (frame.inputStack == null) {
			frame.inputStack = new int[nInputStack + this.outputStackTop];
			changed = true;
		}
		for (int i = 0; i < nInputStack; i++) {
			int t = this.inputStack[i];
			if (this.initializations != null) {
				t = init(cw, t);
			}
			changed |= merge(cw, t, frame.inputStack, i);
		}
		for (int i = 0; i < this.outputStackTop; i++) {
			int s = this.outputStack[i];
			int dim = s & 0xF0000000;
			int kind = s & 0xF000000;
			int t;
			if (kind == 16777216) {
				t = s;
			} else {
				if (kind == 33554432) {
					t = dim + this.inputLocals[(s & 0x7FFFFF)];
				} else {
					t = dim + this.inputStack[(nStack - (s & 0x7FFFFF))];
				}
				if (((s & 0x800000) != 0) && ((t == 16777220) || (t == 16777219))) {
					t = 16777216;
				}
			}
			if (this.initializations != null) {
				t = init(cw, t);
			}
			changed |= merge(cw, t, frame.inputStack, nInputStack + i);
		}
		return changed;
	}

	private static boolean merge(ClassWriter cw, int t, int[] types, int index) {
		int u = types[index];
		if (u == t) {
			return false;
		}
		if ((t & 0xFFFFFFF) == 16777221) {
			if (u == 16777221) {
				return false;
			}
			t = 16777221;
		}
		if (u == 0) {
			types[index] = t;
			return true;
		}
		int v;
		if (((u & 0xFF00000) == 24117248) || ((u & 0xF0000000) != 0)) {
			if (t == 16777221) {
				return false;
			}
			if ((t & 0xFFF00000) == (u & 0xFFF00000)) {
				if ((u & 0xFF00000) == 24117248) {
					v = t & 0xF0000000 | 0x1700000 | cw.getMergedType(t & 0xFFFFF, u & 0xFFFFF);
				} else {
					v = 0x1700000 | cw.addType("java/lang/Object");
				}
			} else {
				if (((t & 0xFF00000) == 24117248) || ((t & 0xF0000000) != 0)) {
					v = 0x1700000 | cw.addType("java/lang/Object");
				} else {
					v = 16777216;
				}
			}
		} else {
			if (u == 16777221) {
				v = ((t & 0xFF00000) == 24117248) || ((t & 0xF0000000) != 0) ? t : 16777216;
			} else {
				v = 16777216;
			}
		}
		if (u != v) {
			types[index] = v;
			return true;
		}
		return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy