If I have a function which returns atom hello , it’s body will look like
{move, {atom, hello}, {x, 0}}
return
But for binary strings, it will look like {move, {literal, <<"hello">>}, {x, 0}}
And for floats, it will be {move, {float, 4.2}, {x, 0}}
And for integers between -2^128 and 2^128 it will look like {move, {integer, 42}, {x, 0}}
But for integers outside of this range it will look like {move, {literal, <Big integer here>}, {x, 0}}
I’ve tried compiling code like {move, {literal, hello}, {x, 0}} and it worked completely fine and raised no warnings.
So what’s the purpose of specifying literal type on assembly level? Is there any runtime performance impact if compiler will always encode atoms literals as literal (not atom) ?
Literals were introduced in OTP R11 (if my memory doesn’t fail me) to be able to have constant lists such as ´[1,2,3]´ or tuples such as {error,enoent}.
I don’t remember exactly why literals can now also be used for representing any term. Could be to simplify some optimization pass.
No. Both way of writing atoms results in exactly the same atom in the runtime system.
There are two types of integers in the runtime system: “smalls” and “bignums”. A small fit into a machine word. The Erlang compiler doesn’t know how many bits that can fit into a small (it depends on whether the runtime system runs on a 32-bit system or a 64-bit system). However, the compiler conservatively assumes that a 24-bit integer will always fit into a small, and an integer having more than 128 bits will never fit into a small.