module.c
Include dependency graph for module.c:
Defines
-
BEAM_TYPE_ATOM (1 << 0)
-
BEAM_TYPE_BITSTRING (1 << 1)
-
BEAM_TYPE_CONS (1 << 2)
-
BEAM_TYPE_FLOAT (1 << 3)
-
BEAM_TYPE_FUN (1 << 4)
-
BEAM_TYPE_INTEGER (1 << 5)
-
BEAM_TYPE_MAP (1 << 6)
-
BEAM_TYPE_NIL (1 << 7)
-
BEAM_TYPE_PID (1 << 8)
-
BEAM_TYPE_PORT (1 << 9)
-
BEAM_TYPE_REFERENCE (1 << 10)
-
BEAM_TYPE_TUPLE (1 << 11)
-
BEAM_TYPE_HAS_LOWER_BOUND (1 << 12)
-
BEAM_TYPE_HAS_UPPER_BOUND (1 << 13)
-
BEAM_TYPE_HAS_UNIT (1 << 14)
-
BEAM_TYPES_VERSION 3
-
LITT_UNCOMPRESSED_SIZE_OFFSET 8
-
LITT_HEADER_SIZE 12
-
CHECK_FREE_SPACE(space, error)
if ((size_t) ((pos + space) - data) > len) { \
fprintf(stderr, error); \
return; \
}
-
DEST_REGISTER(...)
-
DECODE_COMPACT_TERM(dest_term, decode_pc)
-
DECODE_EXTENDED_LIST_TAG(decode_pc)
{ \
if ((*(decode_pc)++) !=
COMPACT_EXTENDED_LIST) { \
fprintf(stderr, "Unexpected operand, expected a list, got %x\n", (decode_pc)[-1]); \
AVM_ABORT(); \
} \
}
-
DECODE_NIL(decode_pc)
{ \
if ((*(decode_pc)++) !=
COMPACT_ATOM) { \
fprintf(stderr, "Unexpected operand, expected nil, got %x\n", (decode_pc)[-1]); \
AVM_ABORT(); \
} \
}
-
DECODE_DEST_REGISTER(dreg, decode_pc)
{ \
uint8_t first_byte = *(decode_pc)++; \
uint8_t reg_type = first_byte & 0xF; \
switch (reg_type) { \
case COMPACT_XREG: \
case COMPACT_YREG: \
break; \
case COMPACT_LARGE_XREG: \
case COMPACT_LARGE_YREG: \
(decode_pc)++; \
break; \
default: \
AVM_ABORT(); \
} \
}
-
DECODE_FP_REGISTER(freg, decode_pc)
{ \
if ((*(decode_pc)++) !=
COMPACT_EXTENDED_FP_REGISTER) { \
fprintf(stderr, "Unexpected operand, expected an fp register, got %x\n", (decode_pc)[-1]); \
AVM_ABORT(); \
} \
DECODE_LITERAL(freg, decode_pc); \
if (freg >
MAX_REG) { \
fprintf(stderr, "FP register index %u >
MAX_REG = %d\n", (unsigned) freg, MAX_REG); \ AVM_ABORT(); \
} \
}
-
DECODE_VALUE32(val, decode_pc)
{ \
uint8_t first_byte = *(decode_pc)++; \
switch (((first_byte) >> 3) & 0x3) { \
case 0: \
case 2: \
val = first_byte >> 4; \
break; \
\
case 1: \
val = ((first_byte & 0xE0) << 3) | *(decode_pc)++; \
break; \
\
case 3: { \
uint8_t sz = (first_byte >> 5) + 2; \
if (sz > 4) { \
fprintf(stderr, "Unexpected operand, expected a literal of at most 4 bytes\n"); \
AVM_ABORT(); \
} \
val = 0; \
for (uint8_t vi = 0; vi < sz; vi++) { \
val <<= 8; \
val |= *(decode_pc)++; \
} \
break; \
} \
default: \
UNREACHABLE(); /* help gcc 8.4 */ \
} \
}
-
DECODE_ATOM(atom, decode_pc)
{ \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_ATOM)) { \
fprintf(stderr, "Unexpected operand, expected an atom (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
uint32_t atom_ix; \
DECODE_VALUE32(atom_ix, decode_pc); \
atom =
module_get_atom_term_by_id(mod, atom_ix); \
}
-
DECODE_LABEL(label, decode_pc)
{ \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_LABEL)) { \
fprintf(stderr, "Unexpected operand, expected a label (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
DECODE_VALUE32(label, decode_pc); \
}
-
DECODE_ATOM_OR_LABEL(atom, label, decode_pc)
{ \
if ((*(decode_pc) &0x7) !=
COMPACT_ATOM) { \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_LABEL)) { \
fprintf(stderr, "Unexpected operand, expected an atom or label (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
atom =
term_invalid_term(); \ DECODE_VALUE32(label, decode_pc); \
} else { \
uint32_t atom_ix; \
DECODE_VALUE32(atom_ix, decode_pc); \
atom =
module_get_atom_term_by_id(mod, atom_ix); \
} \
}
-
DECODE_LITERAL(literal, decode_pc)
{ \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_LITERAL)) { \
fprintf(stderr, "Unexpected operand, expected a literal (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
DECODE_VALUE32(literal, decode_pc); \
}
-
DECODE_XREG(reg, decode_pc)
{ \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_XREG)) { \
fprintf(stderr, "Unexpected operand, expected an xreg (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
DECODE_VALUE32(reg, decode_pc); \
if (reg >
MAX_REG) { \
fprintf(stderr, "Register index %u >
MAX_REG = %d\n", (unsigned) reg, MAX_REG); \ AVM_ABORT(); \
} \
}
-
DECODE_YREG(reg, decode_pc)
{ \
if (
UNLIKELY((*(decode_pc) &0x7) != COMPACT_YREG)) { \
fprintf(stderr, "Unexpected operand, expected a yreg (%x)\n", *(decode_pc)); \
AVM_ABORT(); \
} \
DECODE_VALUE32(reg, decode_pc); \
}
-
IS_EXTENDED_ALLOCATOR(decode_pc) (*decode_pc) == COMPACT_EXTENDED_ALLOCATION_LIST
-
DECODE_ALLOCATOR_LIST(need, decode_pc) if (IS_EXTENDED_ALLOCATOR
(decode_pc)) { \
need = 0; \
(decode_pc)++; /* skip list tag */ \
uint32_t list_size; \
DECODE_LITERAL(list_size, (decode_pc)); \
uint32_t allocator_tag; \
uint32_t allocator_size; \
for (uint32_t j = 0; j < list_size; j++) { \
DECODE_LITERAL(allocator_tag, (decode_pc)); \ DECODE_LITERAL(allocator_size, (decode_pc)); \
if (allocator_tag ==
COMPACT_EXTENDED_ALLOCATOR_LIST_TAG_FLOATS) { \
allocator_size *=
FLOAT_SIZE; \
} else if (allocator_tag ==
COMPACT_EXTENDED_ALLOCATOR_LIST_TAG_FUNS) { \
allocator_size *=
BOXED_FUN_SIZE; \
} \
need += allocator_size; \
} \
} else { \
DECODE_LITERAL(need, decode_pc); \
}
-
X_OPCODE(op_name, num, lower_name, signature) signature,
-
X_OPCODE_HANDLER(op_name, num, lower_name, signature) signature,
-
X_OPCODE_REMOVED(op_name, num, lower_name) NULL,
-
X_OPCODE_SKIP(...) NULL,
-
OPCODE_SIGNATURES_LEN (sizeof(opcode_signatures) / sizeof(opcode_signatures[0]))
-
X_OPCODE(op_name, num, lower_name, signature) NULL,
-
X_OPCODE_HANDLER(op_name, num, lower_name, signature) handle_##lower_name##_opcode,
-
X_OPCODE_REMOVED(op_name, num, lower_name) NULL,
-
X_OPCODE_SKIP(...) NULL,
Typedefs
Functions
-
static bool module_are_literals_compressed(const uint8_t *litT)
-
static struct LiteralEntry *module_build_literals_table(const void *literalsBuf)
-
static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data, GlobalContext *glb)
-
static void handle_fmove_opcode(Module *mod, struct ListHead *line_refs, const uint8_t **current_pc, int arg_index, uint32_t u32_arg)
-
static void handle_bs_match_opcode(Module *mod, struct ListHead *line_refs, const uint8_t **current_pc, int arg_index, uint32_t u32_arg)
-
static void handle_label_opcode(Module *mod, struct ListHead *line_refs, const uint8_t **current_pc, int arg_index, uint32_t u32_arg)
-
static void handle_line_opcode(Module *mod, struct ListHead *line_refs, const uint8_t **current_pc, int arg_index, uint32_t u32_arg)
-
static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, uint8_t *table_data, GlobalContext *glb)
-
void module_get_imported_function_module_and_name(const Module *this_module, int index, AtomString *module_atom, AtomString *function_atom, GlobalContext *glb)
Gets imported function module and name.
Gets imported function module and name given its import table index.
- Parameters:
this_module – the module on which the function will be searched.
index – the modules import table offset to begin searching.
module_atom – module name atom string.
function_atom – function name atom string.
glb – the global context.
-
void module_get_imported_function_module_and_name_atoms(const Module *this_module, int index, term *module_atom, term *function_atom)
Gets imported function module and name atom.
Gets imported function module and name given its import table index.
- Parameters:
this_module – the module on which the function will be searched.
index – the modules import table offset to begin searching.
module_atom – module name atom
function_atom – function name atom
-
bool module_get_function_from_label(Module *this_module, int label, atom_index_t *function_name, int *arity)
-
size_t module_get_exported_functions_count(Module *this_module)
Count exported functions of a given module.
Get the number of exported functions. This function is used to compute the required heap size of the list of exported functions.
- Parameters:
this_module – the module to count exported functions of
- Returns:
the number of exported functions
-
uint32_t module_search_exported_function(Module *this_module, atom_index_t func_name, int func_arity)
Gets exported function index by searching it by function name and arity.
Gets exported function index by searching it by function name and arity
- Parameters:
this_module – the module on which the function will be searched.
func_name – function name atom string.
func_arity – function arity.
-
term module_get_exported_functions(Module *this_module, Heap *heap)
Get the list of exported functions.
Create a list of exported functions of the form
{FunctionName, Arity}To create this list, the heap must be grown bymodule_get_exported_functions_list_sizeterms.- Parameters:
this_module – the module to count exported functions of
heap – heap to allocate tuples
- Returns:
a list of exported functions
-
Module *module_new_from_iff_binary(GlobalContext *global, const void *iff_binary, unsigned long size)
Parse a BEAM file and returns a Module.
Parse a BEAM file a returns a newly allocated and initialized Module struct.
- Parameters:
global – the global context.
iff_binary – the IFF file data.
size – the size of the buffer containing the IFF data.
-
term module_load_literal(Module *mod, int index, Context *ctx)
Gets a literal stored on the literal table of the specified module.
Loads and deserialize a term stored in the literal table and returns a term.
- Parameters:
mod – The module that owns that is going to be loaded.
index – a valid literal index.
ctx – the target context.
-
term module_get_type_by_index(const Module *mod, int type_index, Context *ctx)
Gets type information for the given type index.
Loads and parses type information from the Type chunk and returns the type.
- Parameters:
mod – The module that owns the type information.
type_index – a valid type index.
ctx – the target context.
-
ModuleNativeEntryPoint module_get_native_entry_point(Module *module, int exported_label)
Get the entry point to native code for a given exported label.
This function is used to call native code.
- Parameters:
module – the module
exported_label – label to get the native entry point to
- Returns:
the native entry point
-
static const struct ExportedFunction *module_create_function(Module *found_module, int exported_label)
-
const struct ExportedFunction *module_resolve_function0(Module *mod, int import_table_index, struct UnresolvedFunctionCall *unresolved, GlobalContext *glb)
-
static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint32_t *out_line, uint16_t *out_location)
-
static bool module_get_location(Module *mod, uint16_t location_ix, size_t *filename_len, const uint8_t **filename)
-
void module_insert_line_ref_offset(Module *mod, struct ListHead *line_refs, uint32_t line_ref, int offset)
-
static bool module_find_line_ref(Module *mod, uint16_t line_ref, uint32_t *line, size_t *filename_len, const uint8_t **filename)
-
bool module_find_line(Module *mod, unsigned int offset, uint32_t *line, size_t *filename_len, const uint8_t **filename)
-
void module_cp_to_label_offset(term cp, Module **cp_mod, int *label, int *l_off, long *out_mod_offset, GlobalContext *global)
Variables
-
static const char *const opcode_signatures[] = {NULL,}
-
static label_opcode_handler_t const opcode_handlers[] = {NULL,}
-
struct LineRefOffset
Collaboration diagram for LineRefOffset: