From fdda36ceda432b31120466f50303c31e59b1b387 Mon Sep 17 00:00:00 2001 From: Vincent Rasquier Date: Thu, 14 Dec 2017 16:43:51 +0100 Subject: [PATCH] Keep working on classreader and finish readCode --- asm/classreader.go | 580 ++++++++++++++++++++++++++++++++++++- asm/constants/constants.go | 212 ++++++++++++-- asm/frame/frame.go | 58 ++++ asm/methodvisitor.go | 6 +- asm/opcodes/opcodes.go | 30 -- asm/symbol/symbol.go | 43 ++- 6 files changed, 838 insertions(+), 91 deletions(-) create mode 100644 asm/frame/frame.go diff --git a/asm/classreader.go b/asm/classreader.go index 444fea4..699a62f 100644 --- a/asm/classreader.go +++ b/asm/classreader.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" + "github.com/leaklessgfy/asm/asm/constants" + "github.com/leaklessgfy/asm/asm/frame" "github.com/leaklessgfy/asm/asm/opcodes" "github.com/leaklessgfy/asm/asm/symbol" ) @@ -794,13 +796,583 @@ func (c ClassReader) readCode(methodVisitor MethodVisitor, context *Context, cod bytecodeOffset := currentOffset - bytecodeStartOffset opcode := b[currentOffset] & 0xFF switch opcode { - case opcodes.NOP, opcodes.ACONST_NULL, opcodes.ICONST_M1, opcodes.ICONST_0, opcodes.ICONST_1, opcodes.ICONST_2, - opcodes.ICONST_3, opcodes.ICONST_4, opcodes.ICONST_5, opcodes.LCONST_0, opcodes.LCONST_1, opcodes.FCONST_0, opcodes.FCONST_1, - opcodes.FCONST_2, opcodes.DCONST_0, opcodes.DCONST_1: + case constants.NOP, constants.ACONST_NULL, constants.ICONST_M1, constants.ICONST_0, constants.ICONST_1, constants.ICONST_2, + constants.ICONST_3, constants.ICONST_4, constants.ICONST_5, constants.LCONST_0, constants.LCONST_1, constants.FCONST_0, constants.FCONST_1, + constants.FCONST_2, constants.DCONST_0, constants.DCONST_1, constants.IALOAD, constants.LALOAD, constants.FALOAD, constants.DALOAD, + constants.AALOAD, constants.BALOAD, constants.CALOAD, constants.SALOAD, constants.IASTORE, constants.LASTORE, constants.FASTORE, constants.DASTORE, + constants.AASTORE, constants.BASTORE, constants.CASTORE, constants.SASTORE, constants.POP, constants.POP2, constants.DUP, constants.DUP_X1, constants.DUP_X2, + constants.DUP2, constants.DUP2_X1, constants.DUP2_X2, constants.SWAP, constants.IADD, constants.LADD, constants.FADD, constants.DADD, constants.ISUB, + constants.LSUB, constants.FSUB, constants.DSUB, constants.IMUL, constants.LMUL, constants.FMUL, constants.DMUL, constants.IDIV, constants.LDIV, constants.FDIV, + constants.DDIV, constants.IREM, constants.LREM, constants.FREM, constants.DREM, constants.INEG, constants.LNEG, constants.FNEG, constants.DNEG, constants.ISHL, + constants.LSHL, constants.ISHR, constants.LSHR, constants.IUSHR, constants.LUSHR, constants.IAND, constants.LAND, constants.IOR, constants.LOR, constants.IXOR, + constants.LXOR, constants.I2L, constants.I2F, constants.I2D, constants.L2I, constants.L2F, constants.L2D, constants.F2I, constants.F2L, constants.F2D, + constants.D2I, constants.D2L, constants.D2F, constants.I2B, constants.I2C, constants.I2S, constants.LCMP, constants.FCMPL, constants.FCMPG, constants.DCMPL, + constants.DCMPG, constants.IRETURN, constants.LRETURN, constants.FRETURN, constants.DRETURN, constants.ARETURN, constants.RETURN, constants.ARRAYLENGTH, + constants.ATHROW, constants.MONITORENTER, constants.MONITOREXIT, constants.ILOAD_0, constants.ILOAD_1, constants.ILOAD_2, constants.ILOAD_3, constants.LLOAD_0, + constants.LLOAD_1, constants.LLOAD_2, constants.LLOAD_3, constants.FLOAD_0, constants.FLOAD_1, constants.FLOAD_2, constants.FLOAD_3, constants.DLOAD_0, + constants.DLOAD_1, constants.DLOAD_2, constants.DLOAD_3, constants.ALOAD_0, constants.ALOAD_1, constants.ALOAD_2, constants.ALOAD_3, constants.ISTORE_0, + constants.ISTORE_1, constants.ISTORE_2, constants.ISTORE_3, constants.LSTORE_0, constants.LSTORE_1, constants.LSTORE_2, constants.LSTORE_3, constants.FSTORE_0, + constants.FSTORE_1, constants.FSTORE_2, constants.FSTORE_3, constants.DSTORE_0, constants.DSTORE_1, constants.DSTORE_2, constants.DSTORE_3, constants.ASTORE_0, + constants.ASTORE_1, constants.ASTORE_2, constants.ASTORE_3: currentOffset++ break + case constants.IFEQ, constants.IFNE, constants.IFLT, constants.IFGE, constants.IFGT, constants.IFLE, constants.IF_ICMPEQ, constants.IF_ICMPNE, constants.IF_ICMPLT, + constants.IF_ICMPGE, constants.IF_ICMPGT, constants.IF_ICMPLE, constants.IF_ACMPEQ, constants.IF_ACMPNE, constants.GOTO, constants.JSR, constants.IFNULL, + constants.IFNONNULL: + c.createLabel(bytecodeOffset+int(c.readShort(currentOffset+1)), labels) + currentOffset += 3 + break + case constants.ASM_IFEQ, constants.ASM_IFNE, constants.ASM_IFLT, constants.ASM_IFGE, constants.ASM_IFGT, constants.ASM_IFLE, constants.ASM_IF_ICMPEQ, + constants.ASM_IF_ICMPNE, constants.ASM_IF_ICMPLT, constants.ASM_IF_ICMPGE, constants.ASM_IF_ICMPGT, constants.ASM_IF_ICMPLE, constants.ASM_IF_ACMPEQ, + constants.ASM_IF_ACMPNE, constants.ASM_GOTO, constants.ASM_JSR, constants.ASM_IFNULL, constants.ASM_IFNONNULL: + c.createLabel(bytecodeOffset+c.readUnsignedShort(currentOffset+1), labels) + currentOffset += 3 + break + case constants.GOTO_W, constants.JSR_W, constants.ASM_GOTO_W: + c.createLabel(bytecodeOffset+c.readInt(currentOffset+1), labels) + currentOffset += 5 + break + case constants.WIDE: + if (b[currentOffset+1] & 0xFF) == opcodes.IINC { + currentOffset += 6 + } else { + currentOffset += 4 + } + break + case constants.TABLESWITCH: + currentOffset += 4 - (bytecodeOffset & 3) + c.createLabel(bytecodeOffset+c.readInt(currentOffset), labels) + numTableEntries := c.readInt(currentOffset+8) - c.readInt(currentOffset+4) + 1 + currentOffset += 12 + for numTableEntries > 0 { + c.createLabel(bytecodeOffset+c.readInt(currentOffset), labels) + currentOffset += 4 + numTableEntries-- + } + break + case constants.LOOKUPSWITCH: + currentOffset += 4 - (bytecodeOffset & 3) + c.createLabel(bytecodeOffset+c.readInt(currentOffset), labels) + numSwitchCases := c.readInt(currentOffset + 4) + currentOffset += 8 + for numSwitchCases > 0 { + c.createLabel(bytecodeOffset+c.readInt(currentOffset+4), labels) + currentOffset += 8 + numSwitchCases-- + } + break + case constants.ILOAD, constants.LLOAD, constants.FLOAD, constants.DLOAD, constants.ALOAD, constants.ISTORE, + constants.LSTORE, constants.FSTORE, constants.DSTORE, constants.ASTORE, constants.RET, constants.BIPUSH, constants.NEWARRAY, constants.LDC: + currentOffset += 2 + break + case constants.SIPUSH, constants.LDC_W, constants.LDC2_W, constants.GETSTATIC, constants.PUTSTATIC, constants.GETFIELD, constants.PUTFIELD, + constants.INVOKEVIRTUAL, constants.INVOKESPECIAL, constants.INVOKESTATIC, constants.NEW, constants.ANEWARRAY, constants.CHECKCAST, constants.INSTANCEOF, + constants.IINC: + currentOffset += 3 + break + case constants.INVOKEINTERFACE, constants.INVOKEDYNAMIC: + currentOffset += 5 + break + case constants.MULTIANEWARRAY: + currentOffset += 4 + break + default: + //throw error + } + } + + { + exceptionTableLength := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for exceptionTableLength > 0 { + start := c.createLabel(c.readUnsignedShort(currentOffset), labels) + end := c.createLabel(c.readUnsignedShort(currentOffset+2), labels) + handler := c.createLabel(c.readUnsignedShort(currentOffset+4), labels) + catchType := c.readUTF8(c.cpInfoOffsets[c.readUnsignedShort(currentOffset+6)], charBuffer) + currentOffset += 8 + methodVisitor.VisitTryCatchBlock(start, end, handler, catchType) + exceptionTableLength-- + } + } + + stackMapFrameOffset := 0 + stackMapTableEndOffset := 0 + compressedFrames := true + localVariableTableOffset := 0 + localVariableTypeTableOffset := 0 + var visibleTypeAnnotationOffsets []int + var invisibleTypeAnnotationOffsets []int + var attributes *Attribute + + attributesCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for attributesCount > 0 { + attributeName := c.readUTF8(currentOffset, charBuffer) + attributeLength := c.readInt(currentOffset + 2) + currentOffset += 6 + + switch attributeName { + case "LocalVariableTable": + if (context.parsingOptions & SKIP_DEBUG) == 0 { + localVariableTableOffset = currentOffset + localVariableTableLength := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for localVariableTableLength > 0 { + startPc := c.readUnsignedShort(currentOffset) + c.createDebugLabel(startPc, labels) + length := c.readUnsignedShort(currentOffset + 2) + c.createDebugLabel(startPc+length, labels) + currentOffset += 10 + localVariableTableLength-- + } + continue + } + break + case "LocalVariableTypeTable": + localVariableTypeTableOffset = currentOffset + break + case "LineNumberTable": + if (context.parsingOptions & SKIP_DEBUG) == 0 { + lineNumberTableLength := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for lineNumberTableLength > 0 { + startPc := c.readUnsignedShort(currentOffset) + lineNumber := c.readUnsignedShort(currentOffset + 2) + currentOffset += 4 + c.createDebugLabel(startPc, labels) + labels[startPc].addLineNumber(lineNumber) + lineNumberTableLength-- + } + continue + } + break + case "RuntimeVisibleTypeAnnotations": + visibleTypeAnnotationOffsets = c.readTypeAnnotations(methodVisitor, context, currentOffset, true) + break + case "RuntimeInvisibleTypeAnnotations": + invisibleTypeAnnotationOffsets = c.readTypeAnnotations(methodVisitor, context, currentOffset, false) + break + case "StackMapTable": + if (context.parsingOptions & SKIP_FRAMES) == 0 { + stackMapFrameOffset = currentOffset + 2 + stackMapTableEndOffset = currentOffset + attributeLength + } + break + case "StackMap": + if (context.parsingOptions & SKIP_FRAMES) == 0 { + stackMapFrameOffset = currentOffset + 2 + stackMapTableEndOffset = currentOffset + attributeLength + compressedFrames = false + } + break + default: + attribute := c.readAttribute(context.attributePrototypes, attributeName, currentOffset, attributeLength, charBuffer, codeOffset, labels) + attribute.nextAttribute = attributes + attributes = attribute + break + } + currentOffset += attributeLength + attributesCount-- + } + + expandFrames := (context.parsingOptions & EXPAND_FRAMS) != 0 + if stackMapFrameOffset != 0 { + context.currentFrameOffset = -1 + context.currentFrameType = 0 + context.currentFrameLocalCount = 0 + context.currentFrameLocalCountDelta = 0 + context.currentFrameLocalTypes = make([]interface{}, maxLocals) + context.currentFrameStackCount = 0 + context.currentFrameStackTypes = make([]interface{}, maxStack) + if expandFrames { + c.computeImplicitFame(context) + } + for offset := stackMapFrameOffset; offset < stackMapTableEndOffset-2; offset++ { + if b[offset] == frame.ITEM_UNINITIALIZED { + potentialBytecodeOffset := c.readUnsignedShort(offset + 1) + if potentialBytecodeOffset >= 0 && potentialBytecodeOffset < codeLength { + if (b[bytecodeStartOffset+potentialBytecodeOffset] & 0xFF) == opcodes.NEW { + c.createLabel(potentialBytecodeOffset, labels) + } + } + } + } + } + if expandFrames && (context.parsingOptions&EXPAND_ASM_INSNS) != 0 { + methodVisitor.VisitFrame(opcodes.F_NEW, maxLocals, nil, 0, nil) + } + + currentVisibleTypeAnnotationIndex := 0 + currentVisibleTypeAnnotationBytecodeOffset := c.getTypeAnnotationBytecodeOffset(visibleTypeAnnotationOffsets, 0) + currentInvisibleTypeAnnotationIndex := 0 + currentInvisibleTypeAnnotationBytecodeOffset := c.getTypeAnnotationBytecodeOffset(invisibleTypeAnnotationOffsets, 0) + insertFrame := false + + wideJumpOpcodeDelta := 0 + if (context.parsingOptions & EXPAND_ASM_INSNS) == 0 { + wideJumpOpcodeDelta = constants.WIDE_JUMP_OPCODE_DELTA + } + currentOffset = bytecodeStartOffset + + for currentOffset < bytecodeEndOffset { + currentBytecodeOffset := currentOffset - bytecodeStartOffset + currentLabel := labels[currentBytecodeOffset] + if currentLabel != nil { + currentLabel.accept(methodVisitor, (context.parsingOptions&SKIP_DEBUG) == 0) + } + + for stackMapFrameOffset != 0 && (context.currentFrameOffset == currentBytecodeOffset || context.currentFrameOffset == -1) { + if context.currentFrameOffset != -1 { + if !compressedFrames || expandFrames { + methodVisitor.VisitFrame(opcodes.F_NEW, context.currentFrameLocalCount, context.currentFrameLocalTypes, context.currentFrameStackCount, context.currentFrameStackTypes) + } else { + methodVisitor.VisitFrame(context.currentFrameType, context.currentFrameLocalCountDelta, context.currentFrameLocalTypes, context.currentFrameStackCount, context.currentFrameStackTypes) + } + insertFrame = false + } + if stackMapFrameOffset < stackMapTableEndOffset { + stackMapFrameOffset = c.readStackMapFrame(stackMapFrameOffset, compressedFrames, expandFrames, context) + } else { + stackMapFrameOffset = 0 + } } + + if insertFrame { + if context.parsingOptions&EXPAND_FRAMS != 0 { + methodVisitor.VisitFrame(constants.F_INSERT, 0, nil, 0, nil) + } + insertFrame = false + } + + opcode := b[currentOffset] & 0xFF + switch opcode { + case constants.NOP, constants.ACONST_NULL, constants.ICONST_M1, + constants.ICONST_0, constants.ICONST_1, constants.ICONST_2, constants.ICONST_3, constants.ICONST_4, constants.ICONST_5, + constants.LCONST_0, constants.LCONST_1, + constants.FCONST_0, constants.FCONST_1, constants.FCONST_2, + constants.DCONST_0, constants.DCONST_1, + constants.IALOAD, constants.LALOAD, constants.FALOAD, constants.DALOAD, constants.AALOAD, constants.BALOAD, constants.CALOAD, constants.SALOAD, + constants.IASTORE, constants.LASTORE, constants.FASTORE, constants.DASTORE, constants.AASTORE, constants.BASTORE, constants.CASTORE, constants.SASTORE, + constants.POP, constants.POP2, + constants.DUP, constants.DUP_X1, constants.DUP_X2, constants.DUP2, constants.DUP2_X1, constants.DUP2_X2, + constants.SWAP, constants.IADD, constants.LADD, constants.FADD, constants.DADD, + constants.ISUB, constants.LSUB, constants.FSUB, constants.DSUB, + constants.IMUL, constants.LMUL, constants.FMUL, constants.DMUL, + constants.IDIV, constants.LDIV, constants.FDIV, constants.DDIV, + constants.IREM, constants.LREM, constants.FREM, constants.DREM, + constants.INEG, constants.LNEG, constants.FNEG, constants.DNEG, + constants.ISHL, constants.LSHL, constants.ISHR, constants.LSHR, constants.IUSHR, constants.LUSHR, + constants.IAND, constants.LAND, constants.IOR, constants.LOR, constants.IXOR, constants.LXOR, + constants.I2L, constants.I2F, constants.I2D, constants.L2I, constants.L2F, constants.L2D, + constants.F2I, constants.F2L, constants.F2D, + constants.D2I, constants.D2L, constants.D2F, + constants.I2B, constants.I2C, constants.I2S, + constants.LCMP, constants.FCMPL, constants.FCMPG, constants.DCMPL, constants.DCMPG, + constants.IRETURN, constants.LRETURN, constants.FRETURN, constants.DRETURN, constants.ARETURN, constants.RETURN, + constants.ARRAYLENGTH, constants.ATHROW, + constants.MONITORENTER, constants.MONITOREXIT: + methodVisitor.VisitInsn(int(opcode)) + currentOffset++ + break + case constants.ILOAD_0, constants.ILOAD_1, constants.ILOAD_2, constants.ILOAD_3, + constants.LLOAD_0, constants.LLOAD_1, constants.LLOAD_2, constants.LLOAD_3, + constants.FLOAD_0, constants.FLOAD_1, constants.FLOAD_2, constants.FLOAD_3, + constants.DLOAD_0, constants.DLOAD_1, constants.DLOAD_2, constants.DLOAD_3, + constants.ALOAD_0, constants.ALOAD_1, constants.ALOAD_2, constants.ALOAD_3: + opcode -= constants.ILOAD_0 + methodVisitor.VisitVarInsn(int(opcodes.ILOAD+(opcode>>2)), int(opcode&0x3)) + currentOffset++ + break + case constants.ISTORE_0, constants.ISTORE_1, constants.ISTORE_2, constants.ISTORE_3, + constants.LSTORE_0, constants.LSTORE_1, constants.LSTORE_2, constants.LSTORE_3, + constants.FSTORE_0, constants.FSTORE_1, constants.FSTORE_2, constants.FSTORE_3, + constants.DSTORE_0, constants.DSTORE_1, constants.DSTORE_2, constants.DSTORE_3, + constants.ASTORE_0, constants.ASTORE_1, constants.ASTORE_2, constants.ASTORE_3: + opcode -= constants.ISTORE_0 + methodVisitor.VisitVarInsn(int(opcodes.ISTORE+(opcode>>2)), int(opcode&0x3)) + currentOffset++ + break + case constants.IFEQ, constants.IFNE, constants.IFLT, constants.IFGE, constants.IFGT, constants.IFLE, + constants.IF_ICMPEQ, constants.IF_ICMPNE, constants.IF_ICMPLT, constants.IF_ICMPGE, constants.IF_ICMPGT, constants.IF_ICMPLE, + constants.IF_ACMPEQ, constants.IF_ACMPNE, constants.GOTO, constants.JSR, constants.IFNULL, constants.IFNONNULL: + methodVisitor.VisitJumpInsn(int(opcode), labels[currentBytecodeOffset+int(c.readShort(currentOffset+1))]) + currentOffset += 3 + break + case constants.GOTO_W, constants.JSR_W: + methodVisitor.VisitJumpInsn(int(opcode)-wideJumpOpcodeDelta, labels[currentBytecodeOffset+c.readInt(currentOffset+1)]) + currentOffset += 5 + break + case constants.ASM_IFEQ, constants.ASM_IFNE, constants.ASM_IFLT, constants.ASM_IFGE, constants.ASM_IFGT, constants.ASM_IFLE, + constants.ASM_IF_ICMPEQ, constants.ASM_IF_ICMPNE, constants.ASM_IF_ICMPLT, constants.ASM_IF_ICMPGE, constants.ASM_IF_ICMPGT, constants.ASM_IF_ICMPLE, + constants.ASM_IF_ACMPEQ, constants.ASM_IF_ACMPNE, + constants.ASM_GOTO, constants.ASM_JSR, constants.ASM_IFNULL, constants.ASM_IFNONNULL: + { + if opcode < constants.ASM_IFNULL { + opcode = opcode - constants.ASM_OPCODE_DELTA + } else { + opcode = opcode - constants.ASM_IFNULL_OPCODE_DELTA + } + target := labels[currentBytecodeOffset+c.readUnsignedShort(currentOffset+1)] + if opcode == opcodes.GOTO || opcode == opcodes.JSR { + methodVisitor.VisitJumpInsn(int(opcode+constants.WIDE_JUMP_OPCODE_DELTA), target) + } else { + if opcode < opcodes.GOTO { + opcode = ((opcode + 1) ^ 1) - 1 + } else { + opcode = opcode ^ 1 + } + endif := c.createLabel(currentBytecodeOffset+3, labels) + methodVisitor.VisitJumpInsn(int(opcode), endif) + methodVisitor.VisitJumpInsn(constants.GOTO_W, target) + insertFrame = true + } + currentOffset += 3 + break + } + case constants.ASM_GOTO_W: + { + methodVisitor.VisitJumpInsn(constants.GOTO_W, labels[currentBytecodeOffset+c.readInt(currentOffset+1)]) + insertFrame = true + currentOffset += 5 + break + } + case constants.WIDE: + opcode = b[currentOffset+1] & 0xFF + if opcode == opcodes.IINC { + methodVisitor.VisitIincInsn(c.readUnsignedShort(currentOffset+2), int(c.readShort(currentOffset+4))) + currentOffset += 6 + } else { + methodVisitor.VisitVarInsn(int(opcode), c.readUnsignedShort(currentOffset+2)) + currentOffset += 4 + } + break + case constants.TABLESWITCH: + { + currentOffset += 4 - (currentBytecodeOffset & 3) + defaultLabel := labels[currentBytecodeOffset+c.readInt(currentOffset)] + low := c.readInt(currentOffset + 4) + high := c.readInt(currentOffset + 8) + currentOffset += 12 + table := make([]*Label, high-low+1) + for i := 0; i < len(table); i++ { + table[i] = labels[currentBytecodeOffset+c.readInt(currentOffset)] + currentOffset += 4 + } + methodVisitor.VisitTableSwitchInsn(low, high, defaultLabel, table...) + break + } + case constants.LOOKUPSWITCH: + { + currentOffset += 4 - (currentBytecodeOffset & 3) + defaultLabel := labels[currentBytecodeOffset+c.readInt(currentOffset)] + nPairs := c.readInt(currentOffset + 4) + currentOffset += 8 + keys := make([]int, nPairs) + values := make([]*Label, nPairs) + for i := 0; i < nPairs; i++ { + keys[i] = c.readInt(currentOffset) + values[i] = labels[currentBytecodeOffset+c.readInt(currentOffset+4)] + currentOffset += 8 + } + methodVisitor.VisitLookupSwitchInsn(defaultLabel, keys, values) + break + } + case constants.ILOAD, constants.LLOAD, constants.FLOAD, constants.DLOAD, constants.ALOAD, + constants.ISTORE, constants.LSTORE, constants.FSTORE, constants.DSTORE, constants.ASTORE, + constants.RET: + methodVisitor.VisitVarInsn(int(opcode), int(b[currentOffset+1]&0xFF)) + currentOffset += 2 + break + case constants.BIPUSH, constants.NEWARRAY: + methodVisitor.VisitIntInsn(int(opcode), int(b[currentOffset+1])) + currentOffset += 2 + break + case constants.SIPUSH: + methodVisitor.VisitIntInsn(int(opcode), int(c.readShort(currentOffset+1))) + currentOffset += 3 + break + case constants.LDC: + constd, _ := c.readConst(int(b[currentOffset+1]&0xFF), charBuffer) + methodVisitor.VisitLdcInsn(constd) + currentOffset += 2 + break + case constants.LDC_W, constants.LDC2_W: + constd, _ := c.readConst(c.readUnsignedShort(currentOffset+1), charBuffer) + methodVisitor.VisitLdcInsn(constd) + currentOffset += 3 + break + case constants.GETSTATIC, constants.PUTSTATIC, constants.GETFIELD, constants.PUTFIELD, + constants.INVOKEVIRTUAL, constants.INVOKESPECIAL, constants.INVOKESTATIC, constants.INVOKEINTERFACE: + { + cpInfoOffset := c.cpInfoOffsets[c.readUnsignedShort(currentOffset+1)] + nameAndTypeCpInfoOffset := c.cpInfoOffsets[c.readUnsignedShort(cpInfoOffset+2)] + owner := c.readClass(cpInfoOffset, charBuffer) + name := c.readUTF8(nameAndTypeCpInfoOffset, charBuffer) + desc := c.readUTF8(nameAndTypeCpInfoOffset+2, charBuffer) + if opcode < opcodes.INVOKEVIRTUAL { + methodVisitor.VisitFieldInsn(int(opcode), owner, name, desc) + } else { + itf := b[cpInfoOffset-1] == symbol.CONSTANT_INTERFACE_METHODREF_TAG + methodVisitor.VisitMethodInsnB(int(opcode), owner, name, desc, itf) + } + if opcode == opcodes.INVOKEINTERFACE { + currentOffset += 5 + } else { + currentOffset += 3 + } + break + } + case constants.INVOKEDYNAMIC: + { + cpInfoOffset := c.cpInfoOffsets[c.readUnsignedShort(currentOffset+1)] + nameAndTypeCpInfoOffset := c.cpInfoOffsets[c.readUnsignedShort(cpInfoOffset+2)] + name := c.readUTF8(nameAndTypeCpInfoOffset, charBuffer) + desc := c.readUTF8(nameAndTypeCpInfoOffset+2, charBuffer) + bootstrapMethodOffset := context.bootstrapMethodOffsets[c.readUnsignedShort(cpInfoOffset)] + var handle interface{} + //handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer); + bootstrapMethodArguments := make([]interface{}, c.readUnsignedShort(bootstrapMethodOffset+2)) + bootstrapMethodOffset += 4 + for i := 0; i < len(bootstrapMethodArguments); i++ { + bootstrapMethodArguments[i], _ = c.readConst(c.readUnsignedShort(bootstrapMethodOffset), charBuffer) + bootstrapMethodOffset += 2 + } + methodVisitor.VisitInvokeDynamicInsn(name, desc, handle, bootstrapMethodArguments) + currentOffset += 5 + break + } + case constants.NEW, constants.ANEWARRAY, constants.CHECKCAST, constants.INSTANCEOF: + methodVisitor.VisitTypeInsn(int(opcode), c.readClass(currentOffset+1, charBuffer)) + currentOffset += 3 + break + case constants.IINC: + methodVisitor.VisitIincInsn(int(b[currentOffset+1]&0xFF), int(b[currentOffset+2])) + currentOffset += 3 + break + case constants.MULTIANEWARRAY: + methodVisitor.VisitMultiANewArrayInsn(c.readClass(currentOffset+1, charBuffer), int(b[currentOffset+3]&0xFF)) + currentOffset += 4 + break + default: + break + //throw new AssertionError() + } + + for visibleTypeAnnotationOffsets != nil && currentVisibleTypeAnnotationIndex < len(visibleTypeAnnotationOffsets) && currentVisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset { + if currentVisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset { + currentAnnotationOffset := c.readTypeAnnotationTarget(context, visibleTypeAnnotationOffsets[currentVisibleTypeAnnotationIndex]) + annotationDescriptor := c.readUTF8(currentAnnotationOffset, charBuffer) + currentAnnotationOffset += 2 + c.readElementValues(methodVisitor.VisitInsnAnnotation(context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, true), currentAnnotationOffset, true, charBuffer) + } + currentVisibleTypeAnnotationIndex++ + currentVisibleTypeAnnotationBytecodeOffset = c.getTypeAnnotationBytecodeOffset(visibleTypeAnnotationOffsets, currentVisibleTypeAnnotationIndex) + } + + for invisibleTypeAnnotationOffsets != nil && currentInvisibleTypeAnnotationIndex < len(invisibleTypeAnnotationOffsets) && currentInvisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset { + if currentInvisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset { + currentAnnotationOffset := c.readTypeAnnotationTarget(context, invisibleTypeAnnotationOffsets[currentInvisibleTypeAnnotationIndex]) + annotationDescriptor := c.readUTF8(currentAnnotationOffset, charBuffer) + currentAnnotationOffset += 2 + c.readElementValues(methodVisitor.VisitInsnAnnotation(context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, false), currentAnnotationOffset, true, charBuffer) + } + currentInvisibleTypeAnnotationIndex++ + currentInvisibleTypeAnnotationBytecodeOffset = c.getTypeAnnotationBytecodeOffset(invisibleTypeAnnotationOffsets, currentInvisibleTypeAnnotationIndex) + } + } + + if labels[codeLength] != nil { + methodVisitor.VisitLabel(labels[codeLength]) } + + if localVariableTableOffset != 0 && (context.parsingOptions&SKIP_DEBUG) == 0 { + var typeTable []int + if localVariableTypeTableOffset != 0 { + typeTable = make([]int, c.readUnsignedShort(localVariableTypeTableOffset)*3) + currentOffset = localVariableTypeTableOffset + 2 + for i := len(typeTable); i > 0; { + i-- + typeTable[i] = currentOffset + 6 + i-- + typeTable[i] = c.readUnsignedShort(currentOffset + 8) + i-- + typeTable[i] = c.readUnsignedShort(currentOffset) + currentOffset += 10 + } + } + localVariableTableLength := c.readUnsignedShort(localVariableTableOffset) + currentOffset = localVariableTableOffset + 2 + for localVariableTableLength > 0 { + startPc := c.readUnsignedShort(currentOffset) + length := c.readUnsignedShort(currentOffset + 2) + name := c.readUTF8(currentOffset+4, charBuffer) + descriptor := c.readUTF8(currentOffset+6, charBuffer) + index := c.readUnsignedShort(currentOffset + 8) + currentOffset += 10 + var signature string + if typeTable != nil { + for i := 0; i < len(typeTable); i += 3 { + if typeTable[i] == startPc && typeTable[i+1] == index { + signature = c.readUTF8(typeTable[i+2], charBuffer) + break + } + } + } + methodVisitor.VisitLocalVariable(name, descriptor, signature, labels[startPc], labels[startPc+length], index) + localVariableTableLength-- + } + } + + if visibleTypeAnnotationOffsets != nil { + for i := 0; i < len(visibleTypeAnnotationOffsets); i++ { + targetType := c.readByte(visibleTypeAnnotationOffsets[i]) + if targetType == LOCAL_VARIABLE || targetType == RESOURCE_VARIABLE { + currentOffset = c.readTypeAnnotationTarget(context, visibleTypeAnnotationOffsets[i]) + annotationDescriptor := c.readUTF8(currentOffset, charBuffer) + currentOffset += 2 + annotationVisitor := methodVisitor.VisitLocalVariableAnnotation( + context.currentTypeAnnotationTarget, + context.currentTypeAnnotationTargetPath, + context.currentLocalVariableAnnotationRangeStarts, + context.currentLocalVariableAnnotationRangeEnds, + context.currentLocalVariableAnnotationRangeIndices, + annotationDescriptor, + true, + ) + currentOffset = c.readElementValues(annotationVisitor, currentOffset, true, charBuffer) + } + } + } + + if invisibleTypeAnnotationOffsets != nil { + for i := 0; i < len(invisibleTypeAnnotationOffsets); i++ { + targetType := c.readByte(visibleTypeAnnotationOffsets[i]) + if targetType == LOCAL_VARIABLE || targetType == RESOURCE_VARIABLE { + currentOffset = c.readTypeAnnotationTarget(context, invisibleTypeAnnotationOffsets[i]) + annotationDescriptor := c.readUTF8(currentOffset, charBuffer) + currentOffset += 2 + annotationVisitor := methodVisitor.VisitLocalVariableAnnotation( + context.currentTypeAnnotationTarget, + context.currentTypeAnnotationTargetPath, + context.currentLocalVariableAnnotationRangeStarts, + context.currentLocalVariableAnnotationRangeEnds, + context.currentLocalVariableAnnotationRangeIndices, + annotationDescriptor, + false, + ) + currentOffset = c.readElementValues(annotationVisitor, currentOffset, true, charBuffer) + } + } + } + + for attributes != nil { + nextAttribute := attributes.nextAttribute + attributes.nextAttribute = nil + methodVisitor.VisitAttribute(attributes) + attributes = nextAttribute + } + + methodVisitor.VisitMaxs(maxStack, maxLocals) } func (c ClassReader) readLabel(bytecodeOffset int, labels []*Label) *Label { @@ -835,7 +1407,6 @@ func (c ClassReader) getTypeAnnotationBytecodeOffset(typeAnnotationOffsets []int if typeAnnotationOffsets == nil || typeAnnotationIndex >= len(typeAnnotationOffsets) || c.readByte(typeAnnotationOffsets[typeAnnotationIndex]) < INSTANCEOF { return -1 } - return c.readUnsignedShort(typeAnnotationOffsets[typeAnnotationIndex] + 1) } @@ -854,6 +1425,7 @@ func (c ClassReader) readElementValues(annotationVisitor AnnotationVisitor, anno } func (c ClassReader) readElementValue(annotationVisitor AnnotationVisitor, elementValueOffset int, elementName string, charBuffer []rune) int { + //TODO return 0 } diff --git a/asm/constants/constants.go b/asm/constants/constants.go index fe531e5..6a38831 100644 --- a/asm/constants/constants.go +++ b/asm/constants/constants.go @@ -1,25 +1,7 @@ package constants -// ASM specific access flags. -// WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard -// access flags, and also to make sure that these flags are automatically filtered out when -// written in class files (because access flags are stored using 16 bits only). const ACC_CONSTRUCTOR = 0x40000 // method access flag. - -// ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}. - -/** - * A frame inserted between already existing frames. This internal stack map frame type (in - * addition to the ones declared in {@link Opcodes}) can only be used if the frame content can be - * computed from the previous existing frame and from the instructions between this existing frame - * and the inserted one, without any knowledge of the type hierarchy. This kind of frame is only - * used when an unconditional jump is inserted in a method while expanding an ASM specific - * instruction. Keep in sync with Opcodes.java. - */ const F_INSERT = 256 - -// The JVM opcode values which are not part of the ASM public API. -// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html. const LDC_W = 19 const LDC2_W = 20 const ILOAD_0 = 26 @@ -65,22 +47,9 @@ const ASTORE_3 = 78 const WIDE = 196 const GOTO_W = 200 const JSR_W = 201 - -// Constants to convert between normal and wide jump instructions. - -// The delta between the GOTO_W and JSR_W opcodes and GOTO and JUMP. const WIDE_JUMP_OPCODE_DELTA = GOTO_W - GOTO - -// Constants to convert JVM opcodes to the equivalent ASM specific opcodes, and vice versa. - -// The delta between the ASM_IFEQ, ..., ASM_IF_ACMPNE, ASM_GOTO and ASM_JSR opcodes -// and IFEQ, ..., IF_ACMPNE, GOTO and JSR. const ASM_OPCODE_DELTA = 49 - -// The delta between the ASM_IFNULL and ASM_IFNONNULL opcodes and IFNULL and IFNONNULL. const ASM_IFNULL_OPCODE_DELTA = 20 - -// ASM specific opcodes, used for long forward jump instructions. const ASM_IFEQ = IFEQ + ASM_OPCODE_DELTA const ASM_IFNE = IFNE + ASM_OPCODE_DELTA const ASM_IFLT = IFLT + ASM_OPCODE_DELTA @@ -100,3 +69,184 @@ const ASM_JSR = JSR + ASM_OPCODE_DELTA const ASM_IFNULL = IFNULL + ASM_IFNULL_OPCODE_DELTA const ASM_IFNONNULL = IFNONNULL + ASM_IFNULL_OPCODE_DELTA const ASM_GOTO_W = 220 + +const T_BOOLEAN = 4 +const T_CHAR = 5 +const T_FLOAT = 6 +const T_DOUBLE = 7 +const T_BYTE = 8 +const T_SHORT = 9 +const T_INT = 10 +const T_LONG = 11 +const H_GETFIELD = 1 +const H_GETSTATIC = 2 +const H_PUTFIELD = 3 +const H_PUTSTATIC = 4 +const H_INVOKEVIRTUAL = 5 +const H_INVOKESTATIC = 6 +const H_INVOKESPECIAL = 7 +const H_NEWINVOKESPECIAL = 8 +const H_INVOKEINTERFACE = 9 +const F_NEW = -1 +const F_FULL = 0 +const F_APPEND = 1 +const F_CHOP = 2 +const F_SAME = 3 +const F_SAME1 = 4 +const NOP = 0 // visitInsn +const ACONST_NULL = 1 // - +const ICONST_M1 = 2 // - +const ICONST_0 = 3 // - +const ICONST_1 = 4 // - +const ICONST_2 = 5 // - +const ICONST_3 = 6 // - +const ICONST_4 = 7 // - +const ICONST_5 = 8 // - +const LCONST_0 = 9 // - +const LCONST_1 = 10 // - +const FCONST_0 = 11 // - +const FCONST_1 = 12 // - +const FCONST_2 = 13 // - +const DCONST_0 = 14 // - +const DCONST_1 = 15 // - +const BIPUSH = 16 // visitIntInsn +const SIPUSH = 17 // - +const LDC = 18 // visitLdcInsn +const ILOAD = 21 // visitVarInsn +const LLOAD = 22 // - +const FLOAD = 23 // - +const DLOAD = 24 // - +const ALOAD = 25 // - +const IALOAD = 46 // visitInsn +const LALOAD = 47 // - +const FALOAD = 48 // - +const DALOAD = 49 // - +const AALOAD = 50 // - +const BALOAD = 51 // - +const CALOAD = 52 // - +const SALOAD = 53 // - +const ISTORE = 54 // visitVarInsn +const LSTORE = 55 // - +const FSTORE = 56 // - +const DSTORE = 57 // - +const ASTORE = 58 // - +const IASTORE = 79 // visitInsn +const LASTORE = 80 // - +const FASTORE = 81 // - +const DASTORE = 82 // - +const AASTORE = 83 // - +const BASTORE = 84 // - +const CASTORE = 85 // - +const SASTORE = 86 // - +const POP = 87 // - +const POP2 = 88 // - +const DUP = 89 // - +const DUP_X1 = 90 // - +const DUP_X2 = 91 // - +const DUP2 = 92 // - +const DUP2_X1 = 93 // - +const DUP2_X2 = 94 // - +const SWAP = 95 // - +const IADD = 96 // - +const LADD = 97 // - +const FADD = 98 // - +const DADD = 99 // - +const ISUB = 100 // - +const LSUB = 101 // - +const FSUB = 102 // - +const DSUB = 103 // - +const IMUL = 104 // - +const LMUL = 105 // - +const FMUL = 106 // - +const DMUL = 107 // - +const IDIV = 108 // - +const LDIV = 109 // - +const FDIV = 110 // - +const DDIV = 111 // - +const IREM = 112 // - +const LREM = 113 // - +const FREM = 114 // - +const DREM = 115 // - +const INEG = 116 // - +const LNEG = 117 // - +const FNEG = 118 // - +const DNEG = 119 // - +const ISHL = 120 // - +const LSHL = 121 // - +const ISHR = 122 // - +const LSHR = 123 // - +const IUSHR = 124 // - +const LUSHR = 125 // - +const IAND = 126 // - +const LAND = 127 // - +const IOR = 128 // - +const LOR = 129 // - +const IXOR = 130 // - +const LXOR = 131 // - +const IINC = 132 // visitIincInsn +const I2L = 133 // visitInsn +const I2F = 134 // - +const I2D = 135 // - +const L2I = 136 // - +const L2F = 137 // - +const L2D = 138 // - +const F2I = 139 // - +const F2L = 140 // - +const F2D = 141 // - +const D2I = 142 // - +const D2L = 143 // - +const D2F = 144 // - +const I2B = 145 // - +const I2C = 146 // - +const I2S = 147 // - +const LCMP = 148 // - +const FCMPL = 149 // - +const FCMPG = 150 // - +const DCMPL = 151 // - +const DCMPG = 152 // - +const IFEQ = 153 // visitJumpInsn +const IFNE = 154 // - +const IFLT = 155 // - +const IFGE = 156 // - +const IFGT = 157 // - +const IFLE = 158 // - +const IF_ICMPEQ = 159 // - +const IF_ICMPNE = 160 // - +const IF_ICMPLT = 161 // - +const IF_ICMPGE = 162 // - +const IF_ICMPGT = 163 // - +const IF_ICMPLE = 164 // - +const IF_ACMPEQ = 165 // - +const IF_ACMPNE = 166 // - +const GOTO = 167 // - +const JSR = 168 // - +const RET = 169 // visitVarInsn +const TABLESWITCH = 170 // visiTableSwitchInsn +const LOOKUPSWITCH = 171 // visitLookupSwitch +const IRETURN = 172 // visitInsn +const LRETURN = 173 // - +const FRETURN = 174 // - +const DRETURN = 175 // - +const ARETURN = 176 // - +const RETURN = 177 // - +const GETSTATIC = 178 // visitFieldInsn +const PUTSTATIC = 179 // - +const GETFIELD = 180 // - +const PUTFIELD = 181 // - +const INVOKEVIRTUAL = 182 // visitMethodInsn +const INVOKESPECIAL = 183 // - +const INVOKESTATIC = 184 // - +const INVOKEINTERFACE = 185 // - +const INVOKEDYNAMIC = 186 // visitInvokeDynamicInsn +const NEW = 187 // visitTypeInsn +const NEWARRAY = 188 // visitIntInsn +const ANEWARRAY = 189 // visitTypeInsn +const ARRAYLENGTH = 190 // visitInsn +const ATHROW = 191 // - +const CHECKCAST = 192 // visitTypeInsn +const INSTANCEOF = 193 // - +const MONITORENTER = 194 // visitInsn +const MONITOREXIT = 195 // - +const MULTIANEWARRAY = 197 // visitMultiANewArrayInsn +const IFNULL = 198 // visitJumpInsn +const IFNONNULL = 199 // - diff --git a/asm/frame/frame.go b/asm/frame/frame.go new file mode 100644 index 0000000..2c5608e --- /dev/null +++ b/asm/frame/frame.go @@ -0,0 +1,58 @@ +package frame + +const ( + SAME_FRAME = 0 + SAME_LOCALS_1_STACK_ITEM_FRAME = 64 + RESERVED = 128 + SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247 + CHOP_FRAME = 248 + SAME_FRAME_EXTENDED = 251 + APPEND_FRAME = 252 + FULL_FRAME = 255 + + ITEM_TOP = 0 + ITEM_INTEGER = 1 + ITEM_FLOAT = 2 + ITEM_DOUBLE = 3 + ITEM_LONG = 4 + ITEM_NULL = 5 + ITEM_UNINITIALIZED_THIS = 6 + ITEM_OBJECT = 7 + ITEM_UNINITIALIZED = 8 + + ITEM_ASM_BOOLEAN = 9 + ITEM_ASM_BYTE = 10 + ITEM_ASM_CHAR = 11 + ITEM_ASM_SHORT = 12 + + DIM_MASK = 0xF0000000 + KIND_MASK = 0x0F000000 + FLAGS_MASK = 0x00F00000 + VALUE_MASK = 0x000FFFFF + + DIM_SHIFT = 28 + + ARRAY_OF = +1 << DIM_SHIFT + + ELEMENT_OF = -1 << DIM_SHIFT + + CONSTANT_KIND = 0x01000000 + REFERENCE_KIND = 0x02000000 + UNINITIALIZED_KIND = 0x03000000 + LOCAL_KIND = 0x04000000 + STACK_KIND = 0x05000000 + + TOP_IF_LONG_OR_DOUBLE_FLAG = 0x00100000 & FLAGS_MASK + + TOP = CONSTANT_KIND | ITEM_TOP + BOOLEAN = CONSTANT_KIND | ITEM_ASM_BOOLEAN + BYTE = CONSTANT_KIND | ITEM_ASM_BYTE + CHAR = CONSTANT_KIND | ITEM_ASM_CHAR + SHORT = CONSTANT_KIND | ITEM_ASM_SHORT + INTEGER = CONSTANT_KIND | ITEM_INTEGER + FLOAT = CONSTANT_KIND | ITEM_FLOAT + LONG = CONSTANT_KIND | ITEM_LONG + DOUBLE = CONSTANT_KIND | ITEM_DOUBLE + NULL = CONSTANT_KIND | ITEM_NULL + UNINITIALIZED_THIS = CONSTANT_KIND | ITEM_UNINITIALIZED_THIS +) diff --git a/asm/methodvisitor.go b/asm/methodvisitor.go index 2effe17..41f619f 100644 --- a/asm/methodvisitor.go +++ b/asm/methodvisitor.go @@ -28,7 +28,7 @@ type MethodVisitor interface { VisitInsn(opcode int) VisitIntInsn(opcode, operand int) VisitVarInsn(opcode, vard int) - VisitTypeInsn(opcode, typed int) + VisitTypeInsn(opcode int, typed string) VisitFieldInsn(opcode int, owner, name, descriptor string) VisitMethodInsn(opcode int, owner, name, descriptor string) VisitMethodInsnB(opcode int, owner, name, descriptor string, isInterface bool) @@ -38,13 +38,13 @@ type MethodVisitor interface { VisitLdcInsn(value interface{}) VisitIincInsn(vard, increment int) VisitTableSwitchInsn(min, max int, dflt *Label, labels ...*Label) - VisitLookupSwitchInsn(dflt *Label, keys []int, labels []Label) + VisitLookupSwitchInsn(dflt *Label, keys []int, labels []*Label) VisitMultiANewArrayInsn(descriptor string, numDimensions int) VisitInsnAnnotation(typeRef int, typePath interface{}, descriptor string, visible bool) AnnotationVisitor //TypePath VisitTryCatchBlock(start, end, handler *Label, typed string) VisitTryCatchAnnotation(typeRef int, typePath interface{}, descriptor string, visible bool) AnnotationVisitor //TypePath VisitLocalVariable(name, descriptor, signature string, start, end *Label, index int) - VisitLocalVariableAnnotation(typeRef int, typePath interface{}, start, end *Label, index []int, descriptor string, visible bool) AnnotationVisitor //TypePath + VisitLocalVariableAnnotation(typeRef int, typePath interface{}, start, end []*Label, index []int, descriptor string, visible bool) AnnotationVisitor //TypePath VisitLineNumber(line int, start *Label) VisitMaxs(maxStack int, maxLocals int) VisitEnd() diff --git a/asm/opcodes/opcodes.go b/asm/opcodes/opcodes.go index 7177a7c..8b164e6 100644 --- a/asm/opcodes/opcodes.go +++ b/asm/opcodes/opcodes.go @@ -51,10 +51,6 @@ const T_BYTE = 8 const T_SHORT = 9 const T_INT = 10 const T_LONG = 11 - -// Possible values for the reference_kind field of CONSTANT_MethodHandle_info structures. -// See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8. - const H_GETFIELD = 1 const H_GETSTATIC = 2 const H_PUTFIELD = 3 @@ -64,38 +60,12 @@ const H_INVOKESTATIC = 6 const H_INVOKESPECIAL = 7 const H_NEWINVOKESPECIAL = 8 const H_INVOKEINTERFACE = 9 - -// ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}. - -/** An expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */ const F_NEW = -1 - -/** A compressed frame with complete frame data. */ const F_FULL = 0 - -/** - * A compressed frame where locals are the same as the locals in the previous frame, except that - * additional 1-3 locals are defined, and with an empty stack. - */ const F_APPEND = 1 - -/** - * A compressed frame where locals are the same as the locals in the previous frame, except that - * the last 1-3 locals are absent and with an empty stack. - */ const F_CHOP = 2 - -/** - * A compressed frame with exactly the same locals as the previous frame and with an empty stack. - */ const F_SAME = 3 - -/** -* A compressed frame with exactly the same locals as the previous frame and with a single value -* on the stack. - */ const F_SAME1 = 4 - const NOP = 0 // visitInsn const ACONST_NULL = 1 // - const ICONST_M1 = 2 // - diff --git a/asm/symbol/symbol.go b/asm/symbol/symbol.go index 6d3d056..3d07bbd 100644 --- a/asm/symbol/symbol.go +++ b/asm/symbol/symbol.go @@ -1,26 +1,23 @@ package symbol // CONSTANT_CLASS_TAG The tag value of CONSTANT_Class_info JVMS structures. -var CONSTANT_CLASS_TAG = 7 - -// CONSTANT_FIELDREF_TAG The tag value of CONSTANT_Fieldref_info JVMS structures. -var CONSTANT_FIELDREF_TAG = 9 - -var CONSTANT_METHODREF_TAG = 10 -var CONSTANT_INTERFACE_METHODREF_TAG = 11 -var CONSTANT_STRING_TAG = 8 -var CONSTANT_INTEGER_TAG = 3 -var CONSTANT_FLOAT_TAG = 4 -var CONSTANT_LONG_TAG = 5 -var CONSTANT_DOUBLE_TAG = 6 -var CONSTANT_NAME_AND_TYPE_TAG = 12 -var CONSTANT_UTF8_TAG = 1 -var CONSTANT_METHOD_HANDLE_TAG = 15 -var CONSTANT_METHOD_TYPE_TAG = 16 -var CONSTANT_INVOKE_DYNAMIC_TAG = 18 -var CONSTANT_MODULE_TAG = 19 -var CONSTANT_PACKAGE_TAG = 20 -var BOOTSTRAP_METHOD_TAG = 64 -var TYPE_TAG = 128 -var UNINITIALIZED_TYPE_TAG = 129 -var MERGED_TYPE_TAG = 130 +const CONSTANT_CLASS_TAG = 7 +const CONSTANT_FIELDREF_TAG = 9 +const CONSTANT_METHODREF_TAG = 10 +const CONSTANT_INTERFACE_METHODREF_TAG = 11 +const CONSTANT_STRING_TAG = 8 +const CONSTANT_INTEGER_TAG = 3 +const CONSTANT_FLOAT_TAG = 4 +const CONSTANT_LONG_TAG = 5 +const CONSTANT_DOUBLE_TAG = 6 +const CONSTANT_NAME_AND_TYPE_TAG = 12 +const CONSTANT_UTF8_TAG = 1 +const CONSTANT_METHOD_HANDLE_TAG = 15 +const CONSTANT_METHOD_TYPE_TAG = 16 +const CONSTANT_INVOKE_DYNAMIC_TAG = 18 +const CONSTANT_MODULE_TAG = 19 +const CONSTANT_PACKAGE_TAG = 20 +const BOOTSTRAP_METHOD_TAG = 64 +const TYPE_TAG = 128 +const UNINITIALIZED_TYPE_TAG = 129 +const MERGED_TYPE_TAG = 130