One feature it has is by-default wrapping prevention for it’s Int values. The following code in Swift will cause an exception – you’ll break in a debugger or simply terminate the entire app if you’re running on iOS:
var i:Int8 = 100 i = i + 30
How does this work under the covers? The following screenshots from hopper show us a disassembly of the compiled binaries, in x64 and ARM.
In the above x64 disassembly, the constant 0x14 (20) is added to the low 8 bits of RAX (AL). The SETO instruction then sets the R8 register (R8B) conditionally if the previous ADD has caused an overflow. This value is then tested using TEST, and finally causes a conditional Jump to 0x100001532 if TEST showed R8 having been set (IE, there was an overflow).
The resulting jump if there has been an overflow is simply to UD2 – UnDefined instruction; raise an invalid opcode exception.
ARM follows a fairly similar path, with B.VS conditionally jumping based on overflow being set, branching out to a BRK; trigger a debug breakpoint.
Interestingly, both ARM and x64 in particular places use a full 64-bit register which is still capable of catching an overflow condition when the Swift data type is Int8 (IE triggers exception when incremented beyond 127) This likely is necessary to be synthesized on ARM due to a lack of access to lower 16 and 8 bits.