diff --git a/src/Class/AttributeInfo/Code.zig b/src/Class/AttributeInfo/Code.zig new file mode 100644 index 0000000..f91a8ce --- /dev/null +++ b/src/Class/AttributeInfo/Code.zig @@ -0,0 +1,26 @@ +const std = @import("std"); + +const Class = @import("../../Class.zig"); +const AttributeInfo = Class.AttributeInfo; +const ParseError = Class.ParseError; + +const Instructions = @import("Instructions.zig").Instructions; + +max_stack: u16, +max_locals: u16, +code: []Instructions, +exception_table: []ExceptionHandler, +attributes: []AttributeInfo, + +const Self = @This(); + +pub const ExceptionHandler = struct { + start_pc: u16, + end_pc: u16, + handler_pc: u16, + catch_type: u16, +}; + +pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self { +} + diff --git a/src/Class/AttributeInfo/Instructions.zig b/src/Class/AttributeInfo/Instructions.zig new file mode 100644 index 0000000..b4ec6b6 --- /dev/null +++ b/src/Class/AttributeInfo/Instructions.zig @@ -0,0 +1,582 @@ +const std = @import("std"); + +const InstructionSet = enum(u8) { + aaload = 0x32, + aastore = 0x53, + aconst_null = 0x1, + aload = 0x19, + aload_0 = 0x2a, + aload_1 = 0x2b, + aload_2 = 0x2c, + aload_3 = 0x2d, + anewarray = 0xbd, + areturn = 0xb0, + arraylength = 0xbe, + astore = 0x3a, + astore_0 = 0x4b, + astore_1 = 0x4c, + astore_2 = 0x4d, + astore_3 = 0x4e, + athrow = 0xbf, + baload = 0x33, + bastore = 0x54, + bipush = 0x10, + caload = 0x34, + castore = 0x55, + checkcast = 0xc0, + d2f = 0x90, + d2i = 0x8e, + d2l = 0x8f, + dadd = 0x63, + daload = 0x31, + dastore = 0x52, + dcmpg = 0x98, + dcmpl = 0x97, + dconst_0 = 0xe, + dconst_1 = 0xf, + ddiv = 0x6f, + dload = 0x18, + dload_0 = 0x26, + dload_1 = 0x27, + dload_2 = 0x28, + dload_3 = 0x29, + dmul = 0x6b, + dneg = 0x77, + drem = 0x73, + dreturn = 0xaf, + dstore = 0x39, + dstore_0 = 0x47, + dstore_1 = 0x48, + dstore_2 = 0x49, + dstore_3 = 0x4a, + dsub = 0x67, + dup = 0x59, + dup_x1 = 0x5a, + dup_x2 = 0x5b, + dup2 = 0x5c, + dup2_x1 = 0x5d, + dup2_x2 = 0x5e, + f2d = 0x8d, + f2i = 0x8b, + f2l = 0x8c, + fadd = 0x62, + faload = 0x30, + fastore = 0x51, + fcmpg = 0x96, + fcmpl = 0x95, + fconst_0 = 0xb, + fconst_1 = 0xc, + fconst_2 = 0xd, + fdiv = 0x6e, + fload = 0x17, + fload_0 = 0x22, + fload_1 = 0x23, + fload_2 = 0x24, + fload_3 = 0x25, + fmul = 0x6a, + fneg = 0x76, + frem = 0x72, + freturn = 0xae, + fstore = 0x38, + fstore_0 = 0x43, + fstore_1 = 0x44, + fstore_2 = 0x45, + fstore_3 = 0x46, + fsub = 0x66, + getfield = 0xb4, + getstatic = 0xb2, + goto = 0xa7, + goto_w = 0xc8, + i2b = 0x91, + i2c = 0x92, + i2d = 0x87, + i2f = 0x86, + i2l = 0x85, + i2s = 0x93, + iadd = 0x60, + iaload = 0x2e, + iand = 0x7e, + iastore = 0x4f, + iconst_m1 = 0x2, + iconst_0 = 0x3, + iconst_1 = 0x4, + iconst_2 = 0x5, + iconst_3 = 0x6, + iconst_4 = 0x7, + iconst_5 = 0x8, + idiv = 0x6c, + if_acmpeq = 0xa5, + if_acmpne = 0xa6, + if_icmpeq = 0x9f, + if_icmpne = 0xa0, + if_icmplt = 0xa1, + if_icmpge = 0xa2, + if_icmpgt = 0xa3, + if_icmple = 0xa4, + ifeq = 0x99, + ifne = 0x9a, + iflt = 0x9b, + ifge = 0x9c, + ifgt = 0x9d, + ifle = 0x9e, + ifnonnull = 0xc7, + ifnull = 0xc6, + iinc = 0x84, + iload = 0x15, + iload_0 = 0x1a, + iload_1 = 0x1b, + iload_2 = 0x1c, + iload_3 = 0x1d, + imul = 0x68, + ineg = 0x74, + instanceof = 0xc1, + invokedynamic = 0xba, + invokeinterface = 0xb9, + invokespecial = 0xb7, + invokestatic = 0xb8, + invokevirtual = 0xb6, + ior = 0x80, + irem = 0x70, + ireturn = 0xac, + ishl = 0x78, + ishr = 0x7a, + istore = 0x36, + istore_0 = 0x3b, + istore_1 = 0x3c, + istore_2 = 0x3d, + istore_3 = 0x3e, + isub = 0x64, + iushr = 0x7c, + ixor = 0x82, + jsr = 0xa8, + jsr_2 = 0xc9, + l2d = 0x8a, + l2f = 0x89, + l2i = 0x88, + ladd = 0x61, + laload = 0x2f, + land = 0x7f, + lastore = 0x50, + lcmp = 0x94, + lconst_0 = 0x9, + lconst_1 = 0xa, + ldc = 0x12, + ldc_2 = 0x13, + ldc2_w = 0x14, + ldiv = 0x6d, + lload = 0x16, + lload_0 = 0x1e, + lload_1 = 0x1f, + lload_2 = 0x20, + lload_3 = 0x21, + lmul = 0x69, + lneg = 0x75, + lookupswitch = 0xab, + lor = 0x81, + lrem = 0x71, + lreturn = 0xad, + lshl = 0x79, + lshr = 0x7b, + lstore = 0x37, + lstore_0 = 0x3f, + lstore_1 = 0x40, + lstore_2 = 0x41, + lstore_3 = 0x42, + lsub = 0x65, + lushr = 0x7d, + lxor = 0x83, + monitorenter = 0xc2, + monitorexit = 0xc3, + multianewarray = 0xc5, + new = 0xbb, + newarray = 0xbc, + nop = 0x0, + pop = 0x57, + pop2 = 0x58, + putfield = 0xb5, + putstatic = 0xb3, + ret = 0xa9, + @"return" = 0xb1, + saload = 0x35, + sastore = 0x56, + sipush = 0x11, + swap = 0x5f, + tableswitch = 0xaa, + wide = 0xc4, +}; + +const IndexU8 = struct { + index: u8, +}; + +const IndexU16 = struct { + index: u16, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8) Self { + return .{ .index = (b1 << 8) | b2 }; + } +}; + +const IndexU32 = struct { + index: u32, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8, b3: u8, b4: u8) Self { + return .{ .index = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 }; + } +}; + +const Byte = struct { + byte: u8, +}; + +const BranchU16 = struct { + branch: u16, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8) Self { + return .{ .index = (b1 << 8) | b2 }; + } +}; + +const BranchU32 = struct { + branch: u32, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8, b3: u8, b4: u8) Self { + return .{ .branch = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4 }; + } +}; + +const IInc = struct { + index: u8, + @"const": u8, +}; + +const InvokeDynamic = struct { + index: u16, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8, pad1: u8, pad2: u8) Self { + _ = pad1; + _ = pad2; + return .{ .index = (b1 << 8) | b2 }; + } +}; + +const InvokeInterface = struct { + index: u16, + count: u8, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8, count: u8, pad: u8) Self { + _ = pad; + return .{ .index = (b1 << 8) | b2, .count = count }; + } +}; + +const LookupSwitch = struct { + default: i32, + pairs: []Pair, + + const Pair = struct { + match: u32, + offset: i32, + }; +}; + +const MultiANewArray = struct { + index: u16, + dimensions: u8, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8, dimensions: u8) Self { + return .{ .index = (b1 << 8) | b2, .dimensions = dimensions }; + } +}; + +const NewArray = struct { + array_type: ArrayType, + + const Self = @This(); + + const ArrayType = enum(u8) { + boolean = 4, + char = 5, + float = 6, + double = 7, + byte = 8, + short = 9, + int = 10, + long = 11, + }; + + pub fn from(atype: u8) Self { + const array_type = std.enums.fromInt(ArrayType, atype) orelse { + std.log.err("Invalid array type"); + std.process.exit(1); + }; + return .{ .array_type = array_type }; + } +}; + +const Short = struct { + short: u16, + + const Self = @This(); + + pub fn from(b1: u8, b2: u8) Self { + return .{ .short = (b1 << 8) | b2 }; + } +}; + +const TableSwitch = struct { + default: i32, + low: i32, + hight: i32, + offsets: []i32, +}; + +const Wide = union { + form1: struct { + opcode: ModifiableInstruction, + index: u16, + }, + form2: struct { + // Should always be iinc + opcode: ModifiableInstruction, + index: u16, + @"const": u16, + }, + + const Self = @This(); + + const ModifiableInstruction = enum(u8) { + iload = 0x15, + fload = 0x17, + aload = 0x19, + lload = 0x16, + dload = 0x18, + istore = 0x36, + fstore = 0x38, + astore = 0x3a, + lstore = 0x37, + dstore = 0x39, + ret = 0xa9, + iinc = 0x84, + }; +}; + +const Instructions = union(InstructionSet) { + aaload, + aastore, + aconst_null, + aload: IndexU8, + aload_0, + aload_1, + aload_2, + aload_3, + anewarray: IndexU16, + areturn, + arraylength, + astore: IndexU8, + astore_0, + astore_1, + astore_2, + astore_3, + athrow, + baload, + bastore, + bipush: Byte, + caload, + castore, + checkcast: IndexU16, + d2f, + d2i, + d2l, + dadd, + daload, + dastore, + dcmpg, + dcmpl, + dconst_0, + dconst_1, + ddiv, + dload: IndexU8, + dload_0, + dload_1, + dload_2, + dload_3, + dmul, + dneg, + drem, + dreturn, + dstore: IndexU8, + dstore_0, + dstore_1, + dstore_2, + dstore_3, + dsub, + dup, + dup_x1, + dup_x2, + dup2, + dup2_x1, + dup2_x2, + f2d, + f2i, + f2l, + fadd, + faload, + fastore, + fcmpg, + fcmpl, + fconst_0, + fconst_1, + fconst_2, + fdiv, + fload: IndexU8, + fload_0, + fload_1, + fload_2, + fload_3, + fmul, + fneg, + frem, + freturn, + fstore: IndexU8, + fstore_0, + fstore_1, + fstore_2, + fstore_3, + fsub, + getfield: IndexU16, + getstatic: IndexU16, + goto: IndexU16, + goto_w: IndexU32, + i2b, + i2c, + i2d, + i2f, + i2l, + i2s, + iadd, + iaload, + iand, + iastore, + iconst_m1, + iconst_0, + iconst_1, + iconst_2, + iconst_3, + iconst_4, + iconst_5, + idiv, + if_acmpeq: BranchU16, + if_acmpne: BranchU16, + if_icmpeq: BranchU16, + if_icmpne: BranchU16, + if_icmplt: BranchU16, + if_icmpge: BranchU16, + if_icmpgt: BranchU16, + if_icmple: BranchU16, + ifeq: BranchU16, + ifne: BranchU16, + iflt: BranchU16, + ifge: BranchU16, + ifgt: BranchU16, + ifle: BranchU16, + ifnonnull: BranchU16, + ifnull: BranchU16, + iinc: IInc, + iload: IndexU8, + iload_0, + iload_1, + iload_2, + iload_3, + imul, + ineg, + instanceof: IndexU16, + invokedynamic: InvokeDynamic, + invokeinterface: InvokeInterface, + invokespecial: IndexU16, + invokestatic: IndexU16, + invokevirtual: IndexU16, + ior, + irem, + ireturn, + ishl, + ishr, + istore: IndexU8, + istore_0, + istore_1, + istore_2, + istore_3, + isub, + iushr, + ixor, + jsr: BranchU16, + jsr_w: BranchU32, + l2d, + l2f, + l2i, + ladd, + laload, + land, + lastore, + lcmp, + lconst_0, + lconst_1, + ldc: IndexU8, + ldc_w: IndexU16, + ldc2_w: IndexU16, + ldiv, + lload: IndexU8, + lload_0, + lload_1, + lload_2, + lload_3, + lmul, + lneg, + lookupswitch: LookupSwitch, + lor, + lrem, + lreturn, + lshl, + lshr, + lstore: IndexU8, + lstore_0, + lstore_1, + lstore_2, + lstore_3, + lsub, + lushr, + lxor, + monitorenter, + monitorexit, + mulitanewarray: MultiANewArray, + new: IndexU16, + newarray: NewArray, + nop, + pop, + pop2, + putfield: IndexU16, + putstatic: IndexU16, + ret: IndexU8, + @"return", + saload, + sastore, + sipush: Short, + swap, + tableswitch: TableSwitch, + wide: Wide, +}; +