Dalvik bytecode constraints

Static constraints

Static constraints are constraints on individual elements of the bytecode. They usually can be checked without employing control or data-flow analysis techniques.

Identifier Description Spec equivalent
A1 The insns array must not be empty. 4.8.1.1
A2 The first opcode in the insns array must have index zero. 4.8.1.3
A3 The insns array must only contain valid Dalvik opcodes. 4.8.1.4
A4 The index of instruction n+1 must equal the index of instruction n plus the length of instruction n, taking into account possible operands. 4.8.1.5
A5 The last instruction in the insns array must end at index insns_size-1. 4.8.1.6
A6 All goto and if-<kind> targets must be opcodes within in the same method. 4.8.1.7
A7 All targets of a packed-switch instruction must be opcodes within in the same method. The size and the list of targets must be consistent. 4.8.1.8
A8 All targets of a sparse-switch instruction must be opcodes within in the same method. The corresponding table must be consistent and sorted low-to-high. 4.8.1.9
A9 The B operand of the const-string and const-string/jumbo instructions must be a valid index into the string constant pool. 4.8.1.10
A10 The C operand of the iget<kind> and iput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent an instance field. 4.8.1.12
A11 The C operand of the sget<kind> and sput<kind> instructions must be a valid index into the field constant pool. The referenced entry must represent a static field. 4.8.1.12
A12 The C operand of the invoke-virtual, invoke-super, and invoke-static instructions must be a valid index into the method constant pool. In all cases, the referenced method_id must belong to a class (not an interface). 4.8.1.13
A13 The B operand of the invoke-virtual/range, invoke-super/range, invoke-direct/range, and invoke-static/range instructions must be a valid index into the method constant pool. In all cases, the referenced method_id must belong to a class (not an interface). 4.8.1.13
A14 A method the name of which starts with a '<' must only be invoked implicitly by the VM, not by code originating from a Dex file. The only exception is the instance initializer, which may be invoked by invoke-direct. 4.8.1.14
A15 The C operand of the invoke-interface instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class). 4.8.1.15
A16 The B operand of the invoke-interface/range instruction must be a valid index into the method constant pool. The referenced method_id must belong to an interface (not a class). 4.8.1.15
A17 The B operand of the const-class, check-cast, new-instance, and filled-new-array/range instructions must be a valid index into the type constant pool. 4.8.1.16
A18 The C operand of the instance-of, new-array, and filled-new-array instructions must be a valid index into the type constant pool. 4.8.1.16
A19 The dimensions of an array created by a new-array instruction must be less than 256. 4.8.1.17
A20 The new instruction must not refer to array classes, interfaces, or abstract classes. 4.8.1.18
A21 The type referred to by a new-array instruction must be a valid, non-reference type. 4.8.1.20
A22 All registers referred to by an instruction in a single-width (non-pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size. 4.8.1.21
A23 All registers referred to by an instruction in a double-width (pair) fashion must be valid for the current method. That is, their indices must be non-negative and smaller than registers_size-1. 4.8.1.23

Structural constraints

Structural constraints are constraints on relationships between several elements of the bytecode. They usually can't be checked without employing control or data-flow analysis techniques.

Identifier Description Spec equivalent
B1 The number and types of arguments (registers and immediate values) must always match the instruction. 4.8.2.1
B2 Register pairs must never be broken up. 4.8.2.3
B3 A register (or pair) has to be assigned first before it can be read. 4.8.2.4
B4 An invoke-direct instruction must only invoke an instance initializer or a method in the current class or one of its superclasses. 4.8.2.7
B5 An instance initializer must only be invoked on an uninitialized instance. 4.8.2.8
B6 Instance methods may only be invoked on and instance fields may only be accessed on already initialized instances. 4.8.2.9
B7 A register which holds the result of a new-instance instruction must not be used if the same new-instance instruction is again executed before the instance is initialized. 4.8.2.10
B8 An instance initializer must call another instance initializer (same class or superclass) before any instance members can be accessed. Exceptions are non-inherited instance fields, which can be assigned before calling another initializer, and the Object class in general. 4.8.2.11
B9 All actual method arguments must be assignment-compatible with their respective formal arguments. 4.8.2.12
B10 For each instance method invocation, the actual instance must be assignment-compatible with the class or interface specified in the instruction. 4.8.2.13
B11 A return<kind> instruction must match its method's return type. 4.8.2.14
B12 When accessing protected members of a superclass, the actual type of the instance being accessed must be either the current class or one of its subclasses. 4.8.2.15
B13 The type of a value stored into a static field must be assignment-compatible with or convertible to the field's type. 4.8.2.16
B14 The type of a value stored into a field must be assignment-compatible with or convertible to the field's type. 4.8.2.17
B15 The type of every value stored into an array must be assignment-compatible with the array's component type. 4.8.2.18
B16 The A operand of a throw instruction must be assignment-compatible with java.lang.Throwable. 4.8.2.19
B17 The last reachable instruction of a method must either be a backwards goto or branch, a return, or a throw instruction. It must not be possible to leave the insns array at the bottom. 4.8.2.20
B18 The unassigned half of a former register pair may not be read (is considered invalid) until it has been re-assigned by some other instruction. 4.8.2.3, 4.8.2.4
B19 A move-result<kind> instruction must be immediately preceded (in the insns array) by an invoke-<kind> instruction. The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction. -
B20 A move-result<kind> instruction must be immediately preceded (in actual control flow) by a matching return-<kind> instruction (it must not be jumped to). The only exception is the move-result-object instruction, which may also be preceded by a filled-new-array instruction. -
B21 A move-exception instruction must only appear as the first instruction in an exception handler. -
B22 The packed-switch-data, sparse-switch-data, and fill-array-data pseudo-instructions must not be reachable by control flow. -