-
Notifications
You must be signed in to change notification settings - Fork 0
BEAM Map Instructions
This file contains information about how the BEAM instructions for maps work (or how we think they work - if such information is unavailable).
Currently this file contains speculation, and is not based on documentation.
-type value() :: {x | y | fr, int()}
| nil
| {atom, atom()} | {integer, integer()} | {float, float()}
| {literal, term()}
{test,is_map,FailLabel,[Value]}
Tests wether a value Value is a map, jumping to FailLabel if it is not.
{get_map_elements,
FailLabel,
MapValue,
{list,ElementPairs}}
Reads a number of values from a map MapValue, jumping to label FailLabel if any key is not present.
ElementPairs is a list [Key1, Var1, ..., Keyn, Varn] of value(), where each Keyi is a key to be read, the result put in Vari.
{test,has_map_fields,
FailLabel,
MapValue,
{list,KeyList}}
Tests that a map MapValue contains a number of keys, jumping to label FailLabel if any key is not present. Assumes that MapValue is a map. In practice, is commonly preceeded by an is_map test.
KeyList is a list [Elem1, ..., Elemn] of value(), where each Elemi is a key to check for.
An example, from maps_build_and_match_empty_val.erl, is:
{test,has_map_fields,
{f,13},
{x,0},
{list,[{integer,1337},{literal,{1,2}},{literal,"hi"}]}}
Currently translated to the following ICode:
vmap := [{x, 0}] ## A new ICode variable, vmap, is introduced
vkey1 := [1337] ## A new ICode variable
vres1 := maps:is_key/1(vkey1, vmap) ## A new ICode variable
if vres1 =:= true then LblSuccess1 else [{f, 13}]
LblSuccess1: ## A new ICode label is created
...
vkey3 := ["hi"]
vres3 := maps:is_key/1(vkey3, vmap)
if vres3 =:= true then LblSuccess3 else [{f, 13}]
LblSuccess3:
{put_map_assoc,
FailLabel,
MapValue,
DestinationMapValue,
NrOfArguments,
{list,ElementPairs}}
Where FailLabel is the goto in case of an error, MapValue is the location of the Map before the updates has taken place, DestinationMapValue is the location of the updated Map and ElementPairs is of the format [{'type', Key0},{'type', Value0}...{'type', KeyN},{'type', ValueN}]. Both instructions have the same structure.
Speculation based on the following example:
#{b => 3, 5 => 1} gives {put_map_assoc,{f,0},{x,0},{x,0},1,{list,[{integer,5},{integer,1},{atom,b},{integer,3}]}}