# 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. | -