diff options
Diffstat (limited to 'erts/emulator/beam/jit/beam_jit_common.cpp')
-rw-r--r-- | erts/emulator/beam/jit/beam_jit_common.cpp | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/erts/emulator/beam/jit/beam_jit_common.cpp b/erts/emulator/beam/jit/beam_jit_common.cpp index b1a43206d8..d03ca7fcfd 100644 --- a/erts/emulator/beam/jit/beam_jit_common.cpp +++ b/erts/emulator/beam/jit/beam_jit_common.cpp @@ -664,11 +664,7 @@ Eterm beam_jit_bs_init_bits(Process *c_p, Binary *bptr; ProcBin *pb; - test_bin_vheap(c_p, - reg, - num_bytes / sizeof(Eterm), - alloc, - Live); + test_bin_vheap(c_p, reg, num_bytes / sizeof(Eterm), alloc, Live); /* * Allocate the binary struct itself. @@ -742,6 +738,111 @@ Eterm beam_jit_bs_get_integer(Process *c_p, return erts_bs_get_integer_2(c_p, size, flags, mb); } +void beam_jit_bs_construct_fail_info(Process *c_p, + Uint packed_error_info, + Eterm bad_value) { + Eterm *hp = HAlloc(c_p, Sint(MAP3_SZ + 3 + 1)); + Eterm cause_tuple; + Eterm error_info; + Uint segment = BSC_GET_SEGMENT(packed_error_info); + Uint op = BSC_GET_OP(packed_error_info); + Uint info = BSC_GET_INFO(packed_error_info); + Uint reason = BSC_GET_REASON(packed_error_info); + Eterm Op = am_none; + Eterm Info = am_none; + + switch (op) { + case BSC_OP_BINARY: + Op = am_binary; + break; + case BSC_OP_FLOAT: + Op = am_float; + break; + case BSC_OP_INTEGER: + Op = am_integer; + break; + case BSC_OP_UTF8: + Op = am_utf8; + break; + case BSC_OP_UTF16: + Op = am_utf16; + break; + case BSC_OP_UTF32: + Op = am_utf32; + break; + } + + switch (reason) { + case BSC_REASON_FREASON: + reason = c_p->freason; + break; + case BSC_REASON_BADARG: + reason = BADARG; + break; + case BSC_REASON_SYSTEM_LIMIT: + reason = SYSTEM_LIMIT; + break; + case BSC_REASON_DEPENDS: + if ((is_small(bad_value) && signed_val(bad_value) >= 0) || + (is_big(bad_value) && !big_sign(bad_value))) { + reason = SYSTEM_LIMIT; + } else { + reason = BADARG; + } + break; + } + + switch (info) { + case BSC_INFO_FVALUE: + Info = c_p->fvalue; + break; + case BSC_INFO_TYPE: + Info = am_type; + break; + case BSC_INFO_SIZE: + Info = am_size; + break; + case BSC_INFO_NEGATIVE: + Info = am_negative_size; + break; + case BSC_INFO_UNIT: + Info = am_unit; + break; + case BSC_INFO_DEPENDS: + if (reason == SYSTEM_LIMIT) { + Info = am_size; + } else if (is_small(bad_value) || is_big(bad_value)) { + Info = am_negative_size; + } else { + Info = am_size; + } + break; + } + + cause_tuple = TUPLE3(hp, make_small(segment), Op, Info); + hp += 4; + error_info = MAP3(hp, + am_cause, + cause_tuple, + am_function, + am_format_bs_fail, + am_module, + am_erl_erts_errors); + c_p->fvalue = error_info; + c_p->freason = reason | EXF_HAS_EXT_INFO; +} + +Sint beam_jit_bs_bit_size(Eterm term) { + if (is_binary(term)) { + ASSERT(sizeof(Uint) == 8); /* Only support 64-bit machines. */ + Uint byte_size = binary_size(term); + return (Sint)((byte_size << 3) + binary_bitsize(term)); + } + + /* Signal error */ + return (Sint)-1; +} + ErtsMessage *beam_jit_decode_dist(Process *c_p, ErtsMessage *msgp) { if (!erts_proc_sig_decode_dist(c_p, ERTS_PROC_LOCK_MAIN, msgp, 0)) { /* |