Lecture 4: Java Class File Format Preview of lecture 5: WebAssembly runtime semantics - WebAssembly program state consists of: - values: i32, f32, i64, f64, v128, externref - memory, large, byte-address, 64KiB pages - table(s): array of opaque references (to functions) - global variables: individual scalars not aliased by memory - call stack: execution of functions, not aliased by memory - local variables: scalars internal to a function, not aliased by memory - the state in the *host* environment (e.g. JavaScript) - functions in WebAssembly - fixed number of arguments and returns - read/write locals by pushing onto operand stack - arithmetic push/pop on operand stack - structured control flow with block/loop/if/else/end The Java .class file format - Originally designed to only support the Java source language - designed in a different era: 1993-1995 - big-endian: fixed-sized integers for most quantities - primarily because of Sparc CPU architecture - upgrades and additions - version 6: stackmaps: help speed up bytecode verification annotations: additional metadata attached to classes and methods - version 7: invokedynamic: add more support for dynamic languages - most Java source language changes accomplished with little or no classfile changes - many languages now compile *into* JVM classfiles - Kotlin - a Java-like language by JetBrains - Groovy - dynamically-typed scripting language - Scala - advanced functional/object-oriented language - Clojure - List dialect - Virgil - personal language project - Single .class file contains only one class - Contains source-level names (though mangled) - Semantically high-level (methods, objects), but binary - names are significant to the runtime semantics - used as a distribution format for closed-source code - stack machine for operands - jumps and branches for control flow - Detailed description: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.16.1 - Overall structure of a Java class file - magic number (0xCAFEBABE) - version numbers (major/minor) - Constant pool: contains strings, numbers, types, names - access flags: ACC_PUBLIC ACC_FINAL ACC_SUPER ACC_INTERFACE ACC_ABSTRACT ACC_SYNTHETIC ACC_ANNOTATION ACC_ENUM - class name: reference to a string - super class name: reference to a string - interfaces implemented: array of references to strings - fields declared: name, type, and annotations - methods declared - additional attributes: room for extensibility - Types in JVM class files - types are described by *mangled* strings in class files - primitives: B = byte C = char D = double F = float I = int J = long S = short Z = boolean - arrays: [ Type - classes/interfaces: L ; - method descriptors "(" Type* ")" (Type | "V") - signatures - encode Java source-level (generic) types - not used for execution by the VM[1], but instead for source compilation - signatures can be mapped to descriptors via *erasure* - [1] except for reflection - Constant pool entries - consists of an identifying byte, followed by kind-specific data CONSTANT_Class 7 name_index: u16 CONSTANT_Fieldref 9 class_index: u16, name_and_type: u16 CONSTANT_Methodref 10 class_index: u16, name_and_type: u16 CONSTANT_InterfaceMethodref 11 class_index: u16, name_and_type: u16 CONSTANT_String 8 string_index: u16 // must be a utf-8 CONSTANT_Integer 3 bytes: u32 CONSTANT_Float 4 bytes: byte[4] CONSTANT_Long 5 bytes: u64 CONSTANT_Double 6 bytes: byte[0] CONSTANT_NameAndType 12 name: u16, type: u16 CONSTANT_Utf8 1 length: u16, bytes: byte[length] CONSTANT_MethodHandle 15 reference_kind: u8, reference_index: u16 CONSTANT_MethodType 16 descriptor_index: u16 CONSTANT_InvokeDynamic 18 bootstrap_method_index: u16, name_and_type_index: u16 - Field declarations - name: string - access flags: ACC_PUBLIC ACC_PRIVATE ACC_PROTECTED ACC_STATIC ACC_FINAL ACC_VOLATILE ACC_TRANSIENT ACC_SYNTHETIC ACC_ENUM - type: descriptor (field type) - attributes: array of attributes, which can include annotations - Method declarations - name: string - access flags: ACC_PUBLIC ACC_PRIVATE ACC_PROTECTED ACC_STATIC ACC_FINAL ACC_SYNCHRONIZED ACC_BRIDGE ACC_VARARGS ACC_NATIVE ACC_ABSTRACT ACC_STRICT ACC_SYNTHETIC - descriptor: method signature - attributes - Attributes for methods ConstantValue Code StackMapTable Exceptions InnerClasses EnclosingMethod Synthetic Signature SourceFile SourceDebugExtension LineNumberTable LocalVariableTable LocalVariableTypeTable Deprecated RuntimeVisibleAnnotations RuntimeInvisibleAnnotations RuntimeVisibleParameterAnnotations RuntimeInvisibleParameterAnnotations AnnotationDefault BootstrapMethods Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; } Exceptions_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_exceptions; u2 exception_index_table[number_of_exceptions]; } InnerClasses_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_classes; { u2 inner_class_info_index; u2 outer_class_info_index; u2 inner_name_index; u2 inner_class_access_flags; } classes[number_of_classes]; } Bytecode instructions: aaload aastore aconst_null aload - loads a local variable aload_ anewarray areturn arraylength astore astore_ athrow baload bastore bipush caload castore checkcast d2f d2i d2l dadd daload dastore dcmp dconst_ ddiv dload dload_ dmul dneg drem dreturn dstore dstore_ dsub dup dup_x1 dup_x2 dup2 dup2_x1 dup2_x2 f2d f2i f2l fadd faload fastore fcmp fconst_ fdiv fload fload_ fmul fneg frem freturn fstore fstore_ fsub getfield getstatic goto goto_w i2b i2c i2d i2f i2l i2s iadd iaload iand iastore if_acmp if_icmp if ifnonnull ifnull iinc iload iload_ imul ineg instanceof invokedynamic invokeinterface invokespecial invokestatic invokevirtual ior irem ireturn ishl ishr istore istore_ isub iushr ixor l2d l2f l2i ladd laload land lastore lcmp lconst_ ldc ldc_w ldc2_w ldiv lload lload_ lmul lneg lookupswitch lor lrem lreturn lshl lshr lstore lstore_ lsub lushr lxor monitorenter monitorexit multianewarray new newarray nop pop pop2 putfield putstatic return saload sastore sipush swap tableswitch wide -- DEMO --