📄 codegeneration.jrag
字号:
public void emitInstanceof(TypeDecl type) { int p = constantPool().addClass(type.isArrayDecl() ? type.typeDescriptor() : type.constantPoolName()); bytes.emit(Bytecode.INSTANCEOF).add2(p); } public void emitCheckCast(TypeDecl type) { int p = constantPool().addClass(type.isArrayDecl() ? type.typeDescriptor() : type.constantPoolName()); bytes.emit(Bytecode.CHECKCAST).add2(p); } public void emitDup() { bytes.emit(Bytecode.DUP); } public void emitDup2() { bytes.emit(Bytecode.DUP2); } public void emitPop() { bytes.emit(Bytecode.POP); } public void emitSwap() { bytes.emit(Bytecode.SWAP); } public void emitBranchNonNull(int label) { int p = jump(label); bytes.emit(Bytecode.IFNONNULL).add2(p); } public void emitGoto(int label) { int p = jump(label); if(wideGoto) bytes.emitGoto(Bytecode.GOTO_W).add4(p); else { if(p > Short.MAX_VALUE || p < Short.MIN_VALUE) numberFormatError = true; bytes.emitGoto(Bytecode.GOTO).add2(p); } } public void emitJsr(int label) { int p = jump(label); bytes.emit(Bytecode.JSR).add2(p); } public void emitCompare(byte bytecode, int label) { int p = jump(label); bytes.emit(bytecode).add2(p); } public String toString() { return bytes.toString(); } public int size() {return bytes.size();} public int pos() {return bytes.pos();} public byte[] toArray() {return bytes.toArray();} CodeGeneration add(int i) { return add((byte)i); } CodeGeneration add(byte b) { bytes.add(b); return this; } CodeGeneration add2(int index) { bytes.add2(index); return this; } CodeGeneration add4(int index) { bytes.add4(index); return this; } CodeGeneration emit(byte b) { bytes.emit(b); return this; } CodeGeneration emit(byte b, int stackChange) { bytes.emit(b, stackChange); return this; } public int maxStackDepth() { return bytes.maxStackDepth(); } public int stackDepth() { return bytes.stackDepth(); } public void changeStackDepth(int i) { bytes.changeStackDepth(i); } } /************************************************************* * Auxiliary class *************************************************************/ class ByteArray { private int stackDepth = 0; private int maxStackDepth = 0; private int size = 64; private byte[] bytes = new byte[size]; private int pos = 0; private int lastGotoPos = 0; ByteArray add(int i) {return add((byte)i);} ByteArray add(byte b) { if(pos >= size) { byte[] ba = new byte[size * 2]; System.arraycopy(bytes, 0, ba, 0, size); size *= 2; bytes = ba; } bytes[pos++] = b; return this; } ByteArray add4(int i) { add(i >> 24 & 0xff); add(i >> 16 & 0xff); add(i >> 8 & 0xff); add(i & 0xff); return this; } ByteArray add2(int index) { add(index >> 8 & 0xff); add(index & 0xff); return this; } ByteArray emit(byte b) { changeStackDepth(BytecodeDebug.stackChange(b)); add(b); return this; } ByteArray emitGoto(byte b) { changeStackDepth(BytecodeDebug.stackChange(b)); lastGotoPos = pos; add(b); return this; } ByteArray emit(byte b, int stackChange) { changeStackDepth(stackChange); add(b); return this; } public int maxStackDepth() { return maxStackDepth; } public int stackDepth() { return stackDepth; } public void changeStackDepth(int i) { stackDepth += i; if(stackDepth > maxStackDepth) maxStackDepth = stackDepth; } public int pos() {return pos;} public int lastGotoPos() {return lastGotoPos;} public void setPos(int index) { pos = index; } public int size() {return pos;} public byte get(int index) {return bytes[index];} public void set(int index, byte value) {bytes[index] = value;} public String toString() { StringBuffer b = new StringBuffer(); for(int i = 0; i < pos; i++) b.append(" " + bytes[i]); return b.toString(); } public byte[] toArray() { byte[] b = new byte[pos]; System.arraycopy(bytes, 0, b, 0, pos); return b; } } /************************************************************* * Emit methods *************************************************************/ // push constants public static void IntegerLiteral.push(CodeGeneration gen, int value) { switch(value) { case -1: gen.emit(Bytecode.ICONST_M1); break; case 0: gen.emit(Bytecode.ICONST_0); break; case 1: gen.emit(Bytecode.ICONST_1); break; case 2: gen.emit(Bytecode.ICONST_2); break; case 3: gen.emit(Bytecode.ICONST_3); break; case 4: gen.emit(Bytecode.ICONST_4); break; case 5: gen.emit(Bytecode.ICONST_5); break; default: if(value >= -128 && value <= 127) { gen.emit(Bytecode.BIPUSH).add(value); } else if(value >= -32768 && value <= 32767) { gen.emit(Bytecode.SIPUSH).add2(value); } else { int index = gen.constantPool().addConstant(value); if(index < 256) gen.emit(Bytecode.LDC).add(index); else gen.emit(Bytecode.LDC_W).add2(index); } } } public static void LongLiteral.push(CodeGeneration gen, long value) { if(value == 0) gen.emit(Bytecode.LCONST_0); else if(value == 1) gen.emit(Bytecode.LCONST_1); else { int index = gen.constantPool().addConstant(value); gen.emit(Bytecode.LDC2_W).add2(index); } } public static void DoubleLiteral.push(CodeGeneration gen, double value) { if(value == 0) gen.emit(Bytecode.DCONST_0); else if(value == 1) gen.emit(Bytecode.DCONST_1); else { int index = gen.constantPool().addConstant(value); gen.emit(Bytecode.LDC2_W).add2(index); } } public static void FloatingPointLiteral.push(CodeGeneration gen, float value) { if(value == 0) gen.emit(Bytecode.FCONST_0); else if(value == 1) gen.emit(Bytecode.FCONST_1); else if(value == 2) gen.emit(Bytecode.FCONST_2); else { int index = gen.constantPool().addConstant(value); if(index < 256) gen.emit(Bytecode.LDC).add(index); else gen.emit(Bytecode.LDC_W).add2(index); } } public static void StringLiteral.push(CodeGeneration gen, String value) { int index = gen.constantPool().addConstant(value); if(index < 256) gen.emit(Bytecode.LDC).add(index); else gen.emit(Bytecode.LDC_W).add2(index); } public static void BooleanLiteral.push(CodeGeneration gen, boolean value) { gen.emit(value ? Bytecode.ICONST_1 : Bytecode.ICONST_0); } public void TypeDecl.emitPushConstant(CodeGeneration gen, int value) { } public void IntegralType.emitPushConstant(CodeGeneration gen, int value) { IntegerLiteral.push(gen, value); } public void LongType.emitPushConstant(CodeGeneration gen, int value) { LongLiteral.push(gen, value); } public void DoubleType.emitPushConstant(CodeGeneration gen, int value) { DoubleLiteral.push(gen, value); } public void FloatType.emitPushConstant(CodeGeneration gen, int value) { FloatingPointLiteral.push(gen, value); } // push literals public void Literal.emitPushConstant(CodeGeneration gen) { System.out.println("ERROR: Tried to generate bytecode for: " + getClass().getName()); } public void IntegerLiteral.emitPushConstant(CodeGeneration gen) { type().emitPushConstant(gen, constant().intValue()); } public void CharacterLiteral.emitPushConstant(CodeGeneration gen) { type().emitPushConstant(gen, constant().intValue()); } public void FloatingPointLiteral.emitPushConstant(CodeGeneration gen) { FloatingPointLiteral.push(gen, constant().floatValue()); } public void LongLiteral.emitPushConstant(CodeGeneration gen) { LongLiteral.push(gen, constant().longValue()); } public void DoubleLiteral.emitPushConstant(CodeGeneration gen) { DoubleLiteral.push(gen, constant().doubleValue()); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -